【问题标题】:Usage of ReentrantReadWriteLock in javax.swing.plaf.nimbus.ImageCachejavax.swing.plaf.nimbus.ImageCache 中 ReentrantReadWriteLock 的使用
【发布时间】:2016-02-05 02:22:49
【问题描述】:

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

我对@9​​87654323@ 的用法有两个疑问:

我可以理解getImage方法中使用的readLocksetImage方法中使用的writeLock,但为什么flush方法中使用了readLockflush 方法不也是某种“写”,因为它改变了地图:

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

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

【问题讨论】:

    标签: java swing concurrency


    【解决方案1】:

    第二个问题第一:

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

    上面提到的所有点都对应一个图像缓存。至于“为什么不使用ConcurrentHashMap?” - ImageCache 使用没有并发实现的LinkedHashMap。有关原因的猜测,请参阅此 SO 问题:Why there is no ConcurrentLinkedHashMap class in jdk?

    第一个问题:

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

    在查看了javax.swing.plaf.nimbus.ImageCachePixelCountSoftReference 源以及ReentrantReadWriteLockLinkedHashMap 文档后,我没有一个明确的答案。 虽然我对使用readLockflush 感到更加困惑,因为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 发送电子邮件会得到答复,我不知道该怎么做。

    希望有人会过来并提供实际答案。好问题。

    【讨论】:

      猜你喜欢
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      相关资源
      最近更新 更多