出现的原因是因为我们起先使用的是HashMap和HashTable,但是随着并发量的增加,HashMap并没有使用同步,在多线程情况下使用HashMap的时候就会出现并发问题,而HashTable虽然是安全的,但是使用的是synchronized 锁整表 *** 作,这样在性能上将会产生很大的影响。那么如何能设计出一款即安全,在效率上又高的集合呢,这样就有了ConcurrentHashMap的产生。
ConcurrentHashMap采用的是锁分段技术,内部为Segment数组来进行细分,而每个Segment又通过HashEntry数组来进行组装,当进行写 *** 作的时候,只需要对这个key对应的Segment进行加锁 *** 作,加锁同时不会对其他的Segment造成影响。总的Map包含了16个Segment(默认数量),每个Segment内部包含16个HashEntry(默认数量),这样对于这个key所在的Segment加锁的同时,其他15个Segmeng还能正常使用,在性能上有了大大的提升。
同时ConcurrentHashMap只是针对put方法进行了加锁,而对于get方法并没有采用加锁的 *** 作,因为具体的值,在Segment的HashEntry里面是volatile的,基于happens-before(先行发生)原则,对数据的写先行发生于对数据的读,所以再读取的时候获取到的必然是最新的结果。
因为对数组的 *** 作,在主内存和工作内存中,load和use、assgin和store是必然连在一起的,一旦使用(use)发生,那load必先行发生于use之前,use前必然从主内存中加载最新的值到工作内存的变量副本里。而一旦赋值(assgin),必然先行发生于store将值传递给主内存,在write到主内存中去。所以put方式无需加锁也能获取到最新的结果。
size *** 作是先请求2次的count数量,如果有发生变化,则对put、remove、clean进行加锁,在统计完之后unlock。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)