分段锁

分段锁与ConcurrentHashMap的实现原理,今天来用自己的理解类比一下ConcurrentHashMap中分段锁的实现。

ConcurrentHashMap使用了分段锁来保证线程安全,效率比起使用synchronized的HashTable要高的很多。每个集合都可以看作是一个存储东西的房子,HashTable与ConcurrentHashMap存储的都是HashEntry数组(每个数组里面是链表,暂且忽略,直到就好)。

一.HashTable:

在HashTable这个房子中,只有一个房间,就像是一个大仓库,里面是一大长列的存放Entry的货架(数组);只要有一个人进了这个房间,他就会把这个房间锁起来,直到这个人在房间里面做完了事情出来之后才会把门打开。此间如果有其他人想要进去,就只能在外面等这个人把房门打开,然后才能进去。这样的话会导致外面等了很多人,效率不高。

二.ConcurrentHashMap:

在ConcurrentHashMap这个房子中,有许多的房间,每个房间都存着一部分的Entry货架(Entry数组的不同段,将一整个的Entry数组分开了),而这些房间各自又有着不同的锁。一个人在访问某一个房间的时候,会把这个房间锁起来,其他的房间依然是可以进去访问的,这样就大大的提高了效率。

在HashTable中,如果线程A想要访问Entry数组前面位置的元素,线程B想要访问数组尾部的位置的元素,但是A先进房间访问了,那么房子就被锁了,B不得不等待。在ConcurrentHashMap中,A进到了前面位置元素所在的房间访问,B仍然可以去尾部元素所在的房间,因为他们处在不同的房间。

分段锁在我的理解中是先分段再锁,将原本的一整个的Entry数组分成了若干段,分别将这若干段放在了不同的新的Segment数组中(分房间),每个Segment有各自的锁,以此提高效率。


HashTable:

分段锁

 

 ConcurrentHashMap:

分段锁

分段锁其实说的简单一点就是:

容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问

比如:在ConcurrentHashMap中使用了一个包含16个锁的数组,每个锁保护所有散列桶的1/16,其中第N个散列桶由第(N mod 16)个锁来保护。假设使用合理的散列算法使关键字能够均匀的分部,那么这大约能使对锁的请求减少到越来的1/16。也正是这项技术使得ConcurrentHashMap支持多达16个并发的写入线程。

 

分段锁

上一篇:KD-tree/寻找k维树的n个最近邻居和删除


下一篇:tableGroup