![](/img/trans.png)
[英]Nimbus: java.lang.ClassCastException: javax.swing.plaf.nimbus.DerivedColor$UIResource cannot be cast to javax.swing.Painter
[英]Usage of ReentrantReadWriteLock in javax.swing.plaf.nimbus.ImageCache
在讀取JDK代碼時,我試圖找到ReentrantReadWriteLock
一些用法,並且發現唯一的用法是在javax.swing.plaf.nimbus.ImageCache
。
我在這里對ReentrantReadWriteLock
的用法有兩個問題:
我可以理解getImage
方法中使用的readLock
和setImage
方法中使用的writeLock
,但是為什么在flush
方法中使用readLock
? flush
方法也不是某種“寫入”方法,因為它更改了映射:
public void flush() {
lock.readLock().lock();
try {
map.clear();
} finally {
lock.readLock().unlock();
}
}
另一個問題:為什么不在此處使用ConcurrentHashMap
,因為它將提供對不同mapEntries
一些並發寫入,並且比ReadWriteLock
提供更多的並發性?
ReentrantReadWriteLocks
可用於提高某些種類的Collection的並發使用。 僅當預期集合很大,由讀取器線程而不是寫入器線程訪問更多讀取器線程且操作所需的開銷大於同步開銷時,通常這才是值得的。 -來自ReentrantReadWriteLock文檔
上面提到的所有要點都對應於圖像緩存。 至於“為什么不使用ConcurrentHashMap
?” ImageCache
使用的LinkedHashMap
沒有並發實現。 關於為什么的推測,請參考以下SO問題: 為什么jdk中沒有ConcurrentLinkedHashMap類?
我也質疑為什么flush
方法不像setImage
方法那樣使用writeLock
。 畢竟,它是在結構上修改地圖。
在回顧了javax.swing.plaf.nimbus.ImageCache
和PixelCountSoftReference
源以及ReentrantReadWriteLock
和LinkedHashMap
文檔之后,我沒有明確的答案。 盡管我對使用readLock
進行flush
感到困惑,但是由於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發送電子郵件會得到答案,但我不確定該如何解決。
希望有人會提供實際答案。 好問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.