CurrentHashMap基于JDK1.7和1.8的区别

        JDK1.7:ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment实际继承自可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色;HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,每个Segment里包含一个HashEntry数组,我们称之为table,每个HashEntry是一个链表结构的元素。初始化有三个参数:initialCapacity:初始容量大小 ,默认16。loadFactor, 扩容因子,默认0.75,当一个Segment存储的元素数量大于initialCapacity* loadFactor时,该Segment会进行一次扩容。concurrencyLevel 并发度,默认16。并发度可以理解为程序运行时能够同时更新ConccurentHashMap且不产生锁竞争的最大线程数,即ConcurrentHashMap中的分段锁个数,即Segment[]的数组长度。如果并发度设置的过小,会带来严重的锁竞争问题;如果并发度设置的过大,原本位于同一个Segment内的访问会扩散到不同的Segment中,CPU cache命中率会下降,从而引起程序性能下降。

       JDK1.8:已摒弃Segment的概念,直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,是优化过且线程安全的HashMap。在JDK1.8中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本。

  1. JDK1.8取消了segment数组,直接用table保存数据,锁的粒度更小,减少并发冲突的概率;
  2. JDK1.8存储数据时采用了链表+红黑树的形式,纯链表的形式时间复杂度为O(n),红黑树则为O(logn),性能提升很大;
  3. JDK1.8的实现降低锁的粒度,JDK1.7版本锁的粒度是基于Segment的,包含多个HashEntry,而JDK1.8锁的粒度就是HashEntry(首节点);
  4. JDK1.8版本的数据结构变得更加简单,使得操作也更加清晰流畅,已使用synchronized来进行同步,由于粒度的降低,实现的复杂度增加;
  5. JDK1.8使用红黑树来优化链表,红黑树的遍历效率是很快;
  6. JDK1.8使用内置锁synchronized来代替重入锁ReentrantLock。

你可能感兴趣的:(java,多线程,高并发)