ConcurrentHashMap的特性
来源:互联网 发布:windows update 在哪 编辑:程序博客网 时间:2024/06/06 12:41
1.ConcurrentHashMap写操作
ConcurrentHashMap采用了分段锁的设计,只有在同一个分段内才存在竞态关系,不同的分段锁之间没有锁竞争。相比于对整个Map加锁的设计,分段锁大大的提高了高并发环境下的处理能力。
因为ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅需要锁定map的某个部分,而其它的线程不需要等到迭代完成才能访问map。简而言之,在迭代的过程中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。
初始化:
ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
static final int DEFAULT_INITIAL_CAPACITY = 16; /** * The default load factor for this table, used when not * otherwise specified in a constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * The default concurrency level for this table, used when not * otherwise specified in a constructor. */ static final int DEFAULT_CONCURRENCY_LEVEL = 16;
public ConcurrentHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); }
@SuppressWarnings("unchecked") public ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) { if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) throw new IllegalArgumentException(); if (concurrencyLevel > MAX_SEGMENTS) concurrencyLevel = MAX_SEGMENTS; // Find power-of-two sizes best matching arguments int sshift = 0; int ssize = 1; while (ssize < concurrencyLevel) { ++sshift; ssize <<= 1; } this.segmentShift = 32 - sshift; this.segmentMask = ssize - 1;//ssize默认为16,也就是多少个分段 if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; int c = initialCapacity / ssize; if (c * ssize < initialCapacity) ++c; int cap = MIN_SEGMENT_TABLE_CAPACITY; while (cap < c) cap <<= 1; // create segments and segments[0] Segment<K,V> s0 = new Segment<K,V>(loadFactor, (int)(cap * loadFactor), (HashEntry<K,V>[])new HashEntry[cap]); Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize];//这里new了一个分段数组并且初始化了s0 UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0] this.segments = ss; }
可以看出不同的key可能会有不同的段。UNSAFE.getObject(segments, (j << SSHIFT) + SBASE))
put操作的代码:
final V put(K key, int hash, V value, boolean onlyIfAbsent) { HashEntry<K,V> node = tryLock() ? null : scanAndLockForPut(key, hash, value);
重要的是tryLock()这个方法。当线程A进入该方法时。代码逻辑如下:
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
其中c的值为0,于是会将private volatile int state;该变量的值更新为1。如果此时线程B进入该方法那么结果将会
进入scanAndLockForPut方法。
private HashEntry<K,V> scanAndLockForPut(K key, int hash, V value) { HashEntry<K,V> first = entryForHash(this, hash); HashEntry<K,V> e = first; HashEntry<K,V> node = null; int retries = -1; // negative while locating node while (!tryLock()) {如果tryLock返回false,也就是getstate()返回的值是1,相当于A线程还没有释放锁。将会一直处于循环。
直到A线程释放锁。
} finally { unlock(); }
protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; }unlock的操作实际上是吧state更新为0。于是线程B就脱离循环的,这就实现了写操作的同步。只是处于一个分段中。
不同的分段就不需要考虑这些了。总的来说就是一种分片加锁的思想。
阅读全文
0 0
- ConcurrentHashMap的特性
- ConcurrentHashMap特性二
- jdk1.5新特性 ConcurrentHashMap
- jdk1.5新特性 ConcurrentHashMap
- HashMap和ConCurrentHashMap各自的相关特性和区别(浅谈)
- 介绍ConcurrentHashMap以及ConcurrentHashMap的内部实现
- java concurrentHashMap 的详解
- ConcurrentHashMap的一点理解
- JDK1.6的ConcurrentHashMap
- ConcurrentHashMap的原理
- ConcurrentHashMap类的理解
- ConcurrentHashMap的rehash过程
- Java ConcurrentHashMap 的理解
- ConcurrentHashMap 的理解
- ConcurrentHashMap的putIfAbsent方法
- ConcurrentHashMap的实现
- ConcurrentHashMap 的实现原理
- 读书笔记:ConcurrentHashMap的原理
- C++I/O流,一遍文章让你了解IO流
- POJO EJB JAVABEAN 的区别
- Android Studio 之 Bug调试
- uva 107 The Cat in the Hat(数学)
- Cheat Engine破解妙用之一
- ConcurrentHashMap的特性
- common.js
- IDEA快捷键
- HDU
- 自定义vector,还有几个函数没写(懒得写了)
- (1)Shiro笔记-整合Ehcache时缺少默认cache配置异常解决
- Java和JVM简史
- SQL Server触发器语法格式
- box-shadow,font-size=0