点击蓝字
关注不迷途

HashMap是线程不安全的类,那在多线程环境中怎么办呢?
HashTable是一个线程安全的Map,实现原理是使用synchronized修饰每个方法。

使用Collections.synchronizedMap(map)可以将一个线程不安全的Map转化为线程安全的类。

一样的是使用synchronized锁住get、remove等方法。
这样实现的线程安全操作是低效的。
那么,有没有高效的线程安全Map呢?
当然,今天要介绍的ConcurrentHashMap就是相对高效的线程安全的Map类。
先来介绍在JDK1.7中,ConcurrentHashMap实现线程安全的方式吧。
大家都知道JDK1.7中HashMap的底层数据结构就是数组+链表的结构。
ConcurrentHashMap内的结构相差不大。
ConcurrentHashMap使用分段锁的机制来实现线程安全,分段指的是Segment。
ConcurrentHashMap内部维护一个Segment数组,默认大小为16,这个大小初始化后是不会变的,也就是Segment没有扩容机制。
Segment继承于ReentrantLock,内部更像是一个HashMap,维护了HashEntry数组,HashEntry是链表的结构。
在进行put操作时,先计算hash对应Segment数组的索引,再调用相应的Segment对象进行put的操作,put操作会先上锁,执行完再进行解锁,保证put时是线程安全的。

Concurrent默认并发度16,表示可以同时16个线程进行并发写操作,当然前提是每个线程写的Sement不一样。
那在JDK1.8中,ConcurrentHashMap会有什么样的变化呢?
1.8中,完全放弃了分段锁的机制,改用CAS与synchronied相结合来实现线程安全。
同时底层数据结构和HashMap的结构一样是维护一个数组,数组内元素可以是链表结构或红黑树结构。

喜欢本篇内容顺便点个在看吧
