1.在JDK8中,ConcurrentHashMap的数据结构是怎样的?
数组+链表+红黑树,和HashMap一样
- Node数组:
ConcurrentHashMap
内部维护一个Node数组,其中每个Node就是键值对的存储单元。- 链表: 每个Node实际上是一个链表的头节点。当发生哈希冲突时,新的节点会被添加到对应位置的链表中。
- 红黑树: 当链表长度达到一定阈值(默认是8),链表会被转换成红黑树。这是为了在高并发情况下提高查找效率。
2.在JDK8中,ConcurrentHashMap如何保证线程安全的?
运用CAS+synchronized机制
ConcurrentHashMap在putVal方法中,添加元素时,
若链表为空,此时使用CAS乐观锁机制添加元素
若链表不为空,(存在Hash冲突场景)使用synchronized悲观锁来保证线程安全
3.在JDK8中,ConcurrentHashMap的get方法如何保证数据一致性的?
volatile+CAS(修改操作时)
1.
volatile
关键字: 在ConcurrentHashMap
的Node
类中,键值对的value
字段被声明为volatile
。这意味着对该字段的读取和写入操作都是原子的,并且会立即被其他线程可见。这有助于确保当一个线程修改了Node
中的值时,其他线程能够立即看到最新的值。static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;volatile V val;volatile Node<K,V> next;// ... }
2.CAS操作:
ConcurrentHashMap
使用CAS操作来更新Node
中的值。当多个线程同时尝试更新同一个Node
的值时,只有一个线程会成功,其他线程需要重试。这确保了在并发情况下对Node
值的更新是线程安全的。