Java线程安全的集合经常在Java面试被问到,比如:Java线程安全的集合有哪些,下面详解Java线程安全的集合@mikechen
1.ConcurrentHashMap
ConcurrentHashMap使用了锁分段技术、CAS、 volatile 变量来保证线程安全和数据可见性。
在JDK1.7中ConcurrentHashMap采用了数组+Segment+分段锁的方式实现。
如下图所示:
ConcurrentHashMap采用了分段锁机制,内部将整个哈希表分成多个小的段,每个段有自己的锁。
JDK8中ConcurrentHashMap参考了JDK8 HashMap的实现,进行全面升级。
如下图所示:
采用了数组+链表+红黑树的实现方式来设计,JDK8中彻底放弃了Segment转而采用的是Node,其设计思想也不再是JDK1.7中的分段锁思想。
在JDK8中ConcurrentHashMap的结构,采用了synchronized+CAS+HashEntry+红黑树的方式来实现。
示例:
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("A", 1); map.put("B", 2); map.put("C", 3);
2.CopyOnWriteArrayList
CopyOnWriteArrayList是ArrayList的线程安全版本,从它的名字可以推测,CopyOnWriteArrayList是在有写操作的时候会copy一份数据,然后写完再设置成新的数据。
示例:
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("A"); list.add("B"); list.add("C");
线程安全的ArrayList,它的读操作不需要加锁,因为内部使用了一份快照来保证数据的一致性,适用于读操作远远大于写操作的场景。
3.ConcurrentLinkedQueue
ConcurrentLinkedQueue是一个基于链接节点的无界无锁线程安全队列,支持高并发的读写操作。
ConcurrentLinkedQueue采用非阻塞算法实现线程安全,具体来说是通过使用CAS(Compare And Swap)原子操作来实现线程安全,而不需要使用锁。
CAS实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true,否则,返回 false。
如下图所示:
示例:
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>(); queue.offer("A"); queue.offer("B"); queue.offer("C");
4.ConcurrentSkipListMap
线程安全的有序映射表,内部使用跳表实现,支持高并发读写。
ConcurrentSkipListMap 使用 CAS(Compare And Swap)操作来实现对元素的插入、删除和修改操作,同时也使用了一些类似于乐观锁的并发控制机制来减少锁的使用。
示例:
ConcurrentSkipListMap<String, Integer> map = new ConcurrentSkipListMap<>(); map.put("A", 1); map.put("B", 2); map.put("C", 3);
5.ConcurrentSkipListSet
ConcurrentSkipListSet是线程安全的有序集合,内部使用跳表实现,支持高并发读写。
示例:
ConcurrentSkipListSet<String> set = new ConcurrentSkipListSet<>(); set.add("A"); set.add("B"); set.add("C");
总以上就是Java线程安全的集合详解,更多Java集合,请查看:Java集合(万字图文全面详解)
mikechen睿哥
mikechen睿哥,十余年BAT架构经验,资深技术专家,就职于阿里、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》