Ged*_*bel 23 java concurrency concurrenthashmap java.util.concurrent
根据Java Concurrency in Practice,第11.4.3章说:
锁分裂有时可以扩展到一组变量独立对象的分区锁定,在这种情况下,它被称为锁定条带.例如,ConcurrentHashMap的实现使用一个包含16个锁的数组,每个锁保护1/16的散列桶; 铲斗N由锁定N mod 16保护.
我仍然有理解和可视化锁条纹和铲斗机制的问题.有人可以用很好理解的话来解释这个:)
提前致谢.
Zim*_*oot 47
哈希映射构建在数组上,其中哈希函数将对象映射到基础数组中的元素.假设底层数组有1024个元素 - ConcurrentHashMap实际上将其转换为16个不同的64个元素的子数组,例如{0,63},{64,127}等.每个子数组都有自己的锁,所以修改{0,63}子数组不影响{64,127}子数组 - 一个线程可以写入第一个子数组,而另一个线程写入第二个子数组.
小智 15
锁定a Collections.synchronizedMap()
和a 之间的区别ConcurrentHashMap
如下:
如果多个线程将Collections.synchronizedMap()
频繁访问,则会有很多争用,因为每个方法都使用共享锁进行同步(即,如果线程X调用a上的方法Collections.synchronizedMap()
,则所有其他线程将被阻止调用Collections.synchronizedMap()
直到线程X的任何方法从它调用的方法返回).
A ConcurrentHashMap
具有可变数量的锁(默认值为16),每个锁保护锁中的一段键ConcurrentHashMap
.因此对于ConcurrentHashMap
160键,每个锁将保护10个元素.因此,操作方法上的一个键(get
,put
,set
等...)仅锁定访问上,其中键是在相同的段的一个关键操作的其它方法.例如,如果线程X调用put(0, someObject)
,然后线程Y调用put(10, someOtherObject)
那些调用可以并发执行,并且线程Y不必等待线程X返回put(0, someObject)
.下面提供一个例子.
此外,某些方法例如size()
并且isEmpty()
根本没有保护.虽然这允许更大的并发性,但这意味着它们不是非常一致的(它们不会反映同时发生变化的状态).
public static void main(String[] args) {
ConcurrentHashMap<Integer, Object> map = new ConcurrentHashMap<>(160);
new Thread(new Runnable() {
@Override
public void run() {
map.put(0, "guarded by one lock");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
map.put(10, "guarded by another lock");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
// could print 0, 1, or 2
System.out.println(map.count());
}
}.start();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14360 次 |
最近记录: |