8.19ConCurrentHashMap

一.HashTable的加锁策略的问题:

1.在方法上直接加synchronized,相当于对this加锁,针对同一个对象的任意一个操作都会对this加锁,如果多个线程都想操作,会发生激烈的锁竞争,只能一个一个串行执行,并发量低,执行效率低.

2.一旦发生扩容,会一口气全部完成,相当耗时间,会发生突然间卡了很久的情况.

二.ConCurrentHashMap的改进:

1.(核心)减小锁的粒度,每个链表有一把锁(对头节点对象加锁),大部分情况不涉及锁冲突.

2. 大量使用CAS操作(比如size++),不涉及锁冲突.

3.写操作进行加锁,读操作不加锁,同时读写操作不冲突,如果同时读写,可能会读到旧版数据,但不会读到半个数据.

4.扩容时,化整为零,把旧数组上的数据逐渐往新数组上搬,一段时间内会出现新旧数组并存.

a)新增元素时往新数组上插入.

b)删除元素如果新的数组上没有,就删除旧的.

c)查找元素时新旧数组都要找.

d)修改元素时同意把元素整到新数组上.

上述每个操作都会触发一定程度的搬运,每次搬运一点,就可以保证不会卡很久没有响应,全部搬完后把旧数组销毁.

三.ConCurrentHashMap分段锁

Java8前使用分段锁,java8及以后每个链表一把锁.

分段锁:一把锁管多个链表.

你可能感兴趣的:(java)