寻找合适的同步机制

假设我有以下(伪)代码:


class Cache {

    Entry addIfMissing(String data) {

        // omitted for brevity

    }

    void evictOldEntries() {

        // omitted for brevity

    }

}

class Program {

    private Cache cache = new Cache();


    doWork() { // called from multiple threads

        var entry = cache.addIfMissing("omitted for brevity");

        // work with entry

    }


    static {

        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {

            cache.evictOldEntries();

        }, 10, 10, TimeUnit.MINUTES);

    }

}

我想确保在该evictOldEntries方法运行时程序中的所有其他线程都必须等待它完成。


在这种情况下哪种同步机制合适?


白板的微信
浏览 211回答 3
3回答

侃侃无极

你需要的是这样的:class Cache {    final ReentrantLock lock;    public Cache { lock = new ReentrantLock(); }    Entry addIfMissing(String data) {        lock.lock();        try {            // Add data here        }        finally {            lock.unlock();        }    }    void evictOldEntries() {        if (lock.tryLock()) {           try {              // Evict old entries           }           finally {              lock.unlock();           }        }    }}

阿晨1998

由于您的代码示例和确切要求有点不清楚,因此在这里有点自由。但是这样的事情可能行得通吗?ConcurrentHashMap使用细粒度锁定,因此可以最大限度地减少将条目插入缓存时的瓶颈。逐出线程甚至可以与插入线程同时运行。class Cache<String, CacheEntry> {&nbsp; &nbsp; ConcurrentHashMap<String, CacheEntry> map = new ConcurrentHashMap<String, CacheEntry>();&nbsp; &nbsp; Entry addIfMissing(String data) {&nbsp; &nbsp; &nbsp; &nbsp; map.computeIfAbsent(...);&nbsp; &nbsp; }&nbsp; &nbsp; void evictOldEntries() {&nbsp; &nbsp; &nbsp; &nbsp; Iterator<Map.Entry<String, CacheEntry>> iterator = map.entrySet().iterator();&nbsp; &nbsp; &nbsp; &nbsp; while (iterator.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CacheEntry entry = iterator.next().getValue();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (shouldEvict(entry)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iterator.remove();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

蓝山帝景

我认为ReentrantReadWriteLock正是我所需要的:class Program {&nbsp; &nbsp; private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();&nbsp; &nbsp; void doWork() { // called from multiple threads&nbsp; &nbsp; &nbsp; &nbsp; rwl.readLock().lock();&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var entry = cache.addIfMissing("omitted for brevity");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // work with entry&nbsp; &nbsp; &nbsp; &nbsp; } finally {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rwl.readLock().unlock();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; static {&nbsp; &nbsp; &nbsp; &nbsp; Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rwl.writeLock().lock();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cache.evictOldEntries();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } finally {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rwl.writeLock().unlock();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }, 10, 10, TimeUnit.MINUTES);&nbsp; &nbsp; }}这样一旦获得 writeLock 就doWork必须阻塞,反之亦然。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java