我正在使用Java中的ConcurrentHashMap实现,看起来默认情况下使用了16个锁,这个数字动态变化。
假设一个并发的hashmap的简单实现,其中数据存储在列表中:List<Bin<X, Y>>
。列表以大小32开始,然后使用列表的getHashCode()
函数模当前容量计算索引
class Bin<X, Y> {
List<Pair<X, Y>> myList;
ReentrantReadWriteLock lock;
void put(X key, Y value){
//acquire write lock
}
void Pair<X, Y> get(X key) {
//acquire read lock
}
}
我想知道在上面提到的天真实现中每个bin有一个锁的缺点是什么。我能想到的一个主要缺点是:
Pair
,ReentrantReadWriteLock
和Bin
对象的额外内存开销锁定太多会对CPU产生什么影响?这种方法的更多缺点是什么?
答案 0 :(得分:0)
当然,当你在readLock()/writeLock()
对象上调用Lock
时,这个锁定会有一些开销,至少有一些cas
操作,最坏的情况是线程阻塞。
没有太大的CPU影响,因为如果Lock
(在您的情况下为ReentrantReadWriteLock
),它是基于AbstractQueuedSynchronizer
实现的,并在其中使用cas
操作。
为了消除存储多个ReentrantReadWriteLock
的开销,您可以在特定synchronized
上使用pair
(当然,您将无法使用读/写锁优化,但由于每个bucket只是一个Pair
,而不是一个集合,我认为这里应该没什么可失去的,jvm也可以通过各种方式优化synchronized
个部分。)