jdk1.7 ReentrantLock 分段锁
jdk1.8 CAS+Synchronized
- CAS: compare and swap
① CAS如何保证内部的线程安全?你可以把CAS的过程理解为原子操作,在硬件底层保证了其内部指令执行的连续性。jdk内部实现是通过Unsafe类提供的API来实现的,Unsafe类可以 像C语言的指针一样直接操作内存,并且只允许jdk自带的类使用(JUC紧密的使用了Unsafe类)。
② ConcurrentHashMap 哪里用到了CAS?往往会用CAS来修改一些属性。例如,ConcurrentHashMap采用懒加载的方式,当第一次插入时才会初始化table,如果当前index下为null,此时就会采用CAS的方式去插入(比如多个线程同时监测到当前index下为null,就会都尝试插入)
2. Synchronized
① Synchronized后续的锁升级策略,使得性能更优
源码
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable {
private static final long serialVersionUID = 7249069246763182397L;
静态成员
- 节点Node类,注意和HashMap的不同,val和next用volatile修饰
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;