在javax.swing.plaf.nimbus.ImageCache中使用ReentrantReadWriteLock



在读取JDK代码时,我试图找到ReentrantReadWriteLock的一些用法,发现唯一的用法是在javax.swing.plaf.nimbus.ImageCache

我对这里ReentrantReadWriteLock的使用有两个问题:

我可以理解getImage方法中使用的readLock,以及setImage方法中使用的writeLock,但是为什么在flush方法中使用readLockflush方法不也是某种"写入"吗,因为它会更改地图:

public void flush() {
    lock.readLock().lock();
    try {
        map.clear();
    } finally {
        lock.readLock().unlock();
    }
}

另一个问题:为什么不在这里使用ConcurrentHashMap,因为它会向不同的mapEntries提供一些并发写入并提供比ReadWriteLock更多的并发性?

第二个问题:

ReentrantReadWriteLocks可用于在某些类型的集合的某些用途中提高并发性。通常,仅当集合预计很大、由比编写器线程更多的读取器线程访问,并且需要开销超过同步开销的操作时,这才值得。- 来自ReentrantReadWriteLock文档

上面提到的所有点都对应于图像缓存。至于"为什么不使用ConcurrentHashMap?">——ImageCache使用没有并发实现的LinkedHashMap。有关原因的推测,请参阅以下 SO 问题:为什么 jdk 中没有 ConcurrentLinkedHashMap 类?

第一个问题:

我也质疑为什么flush方法不像setImage方法那样使用writeLock。毕竟,它是在结构上修改地图。

在查看了javax.swing.plaf.nimbus.ImageCachePixelCountSoftReference来源以及ReentrantReadWriteLockLinkedHashMap文档后,我没有明确的答案。虽然我对flush使用readLock感到更加困惑,因为ReentrantReadWriteLock's文档有以下示例,其中在清除TreeMap时使用writeLock

// For example, here is a class using a TreeMap that is expected to be 
// large and concurrently accessed.
class RWDictionary {
    private final Map<String, Data> m = new TreeMap<String, Data>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock w = rwl.writeLock();
    // other code left out for brevity
    public void clear() {
        w.lock();  // write lock
        try { m.clear(); } // clear the TreeMap
        finally { w.unlock(); }
    }
}

我唯一能做的就是推测。

投机:

  • 也许作者犯了一个错误,不太可能,但并非不可能。
  • 这是故意的。我有一些关于为什么可能是故意的想法,但我不确定如何措辞,他们可能是错误的。
  • 作者是唯一使用ImageCache代码的人,并且知道何时以及如何(不(使用flush方法。这也不太可能。

通过电子邮件询问作者为什么他们使用readLock而不是writeLock会很有趣,但来源中没有列出作者或电子邮件。也许向Oracle发送电子邮件会产生答复,我不确定该怎么做。

希望有人会来提供实际的答案。问得好。

相关内容

  • 没有找到相关文章

最新更新