JDK 1.8以前,多个数组,分段加锁,一个数组一个锁
JDK 1.8以后,优化细粒度,一个数组,每个元素进行CAS,如果失败说明有人了,此时synchronized对数组元素加锁,链表+红黑树处理,对数组每个元素加锁
多个线程要访问同一个数据,synchronized加锁,CAS去进行安全的累加,去实现多线程场景下的安全的更新一个数据的效果,比较多的一个场景下,可能就是多个线程同时读写一个HashMap
synchronized,也没这个必要
HashMap的一个底层的原理,本身是一个大的一个数组,[有很多的元素]
ConcurrentHashMap map = new ConcurrentHashMap();
// 多个线程过来,线程1要put的位置是数组[5],线程2要put的位置是数组[21]
map.put(xxxxx,xxx);
明显不好,数组里有很多的元素,除非是对同一个元素执行put操作,此时呢需要多线程是需要进行同步的
JDK并发包里推出了一个ConcurrentHashMap,他默认实现了线程安全性
在JDK 1.7以及之前的版本里,分段
[数组1] , [数组2],[数组3] -> 每个数组都对应一个锁,分段加锁
// 多个线程过来,线程1要put的位置是数组1[5],线程2要put的位置是数组2[21]
JDK 1.8以及之后,做了一些优化和改进,锁粒度的细化
[一个大的数组],数组里每个元素进行put操作,都是有一个不同的锁,刚开始进行put的时候,如果两个线程都是在数组[5]这个位置进行put,这个时候,对数组[5]这个位置进行put的时候,采取的是CAS的策略
同一个时间,只有一个线程能成功执行这个CAS,就是说他刚开始先获取一下数组[5]这个位置的值,null,然后执行CAS,线程1,比较一下,put进去我的这条数据,同时间,其他的线程执行CAS,都会失败
分段加锁,通过对数组每个元素执行CAS的策略,如果是很多线程对数组里不同的元素执行put,大家是没有关系的,如果其他人失败了,其他人此时会发现说,数组[5]这位置,已经给刚才又人放进去值了
就需要在这个位置基于链表+红黑树来进行处理,synchronized(数组[5]),加锁,基于链表或者是红黑树在这个位置插进去自己的数据
如果你是对数组里同一个位置的元素进行操作,才会加锁串行化处理;如果是对数组不同位置的元素操作,此时大家可以并发执行的