concurrentmap
1.concurrentHashmap是设计非阻塞的,在更新的时候会锁住局部部分数据。但不会把整个表都锁住。同步读取操作完全是非阻塞的。在保证合理同步的前提下效率很高。坏处不能保证反应最近的更新。例如线程A调用putAll大量写入数据,期间线程B调用get,则只能get到目前为止顺利插入的数据。
2.JDK1.8版本来看ConcurrentHashMap的数据结构已经趋近于hashmap,相对而言concurrentHashmap只是增加了同步的操作来控制并发。
JDK1.7 使用的ReentrantLock(重入锁)+Segment(分段)+HashEntry
JDK1.8 使用的synchronized+CAS+HashEntry+红黑树
升级的原因思考:
1.JDK1.8的实现降低了锁的粒度,JDK1.7的粒度是基于segment的,包含多个HashEntry,而JDK1.8就是基于HashEntry
2.数据结构的改变。JDK1.8是更具synchronized来进行同步的。所以不需要分段锁的概念
3.JDK1.8使用红黑树来优化链表。长度很长的链表用红黑树提升效率。
4.JDK1.8使用synchronized来替代Reentrantlock的原因
1.粒度降低,相对于低粒度而言,synchronized的效率不比Reentrantlock差。
2.synchronized使用内嵌的关键字比使用API更加自然。
3.在大量数据下,对于JVM的内存压力,基于API的ReentrantLock会开销更多的内存。
hashtable
- hashtable的任何操作都会把整个表锁住,是阻塞的。好处可以看到最新的数据。坏处:所有的操作都需要排队,效率的低。