![](https://img.haomeiwen.com/i4031144/fa7180063aff2b91.png)
扩容时的线程安全性保证:
1、transferIndex是分给每个线程桶空间的上限下标。它的volatile+cas更新保证了每个线程分到的桶空间不会发生重叠。
2、在对桶i进行迁移时,会对桶i处的链表头节点用sunchronized加锁,防止在迁移时别的线程put。
3、对桶i的链表进行迁移时,链表上的节点只会落到两个地方,i和i+table.length。所以各个线程负责的桶空间发生迁移时落到[table.length,2*table.lenth - 1]区间的下标是唯一的,互不干扰。
比如:
table.length = 32,新的数组长度是64。
线程A负责0-15,线程B负责16-31桶空间。
线程A迁移桶8,线程B迁移桶迁移16。
桶8处上的链表只会落到8或者40,桶16处的链表只会落到16或者48。40和48是互不干扰的。
4、扩容过程中,会将迁移完的桶打上标记(节点为forwardingNode),表明这个桶迁移过了,别的线程想在该桶put只能协助扩容或者阻塞(先锁住链表头节点,再去迁移。迁移中时想put,由于取不到链表头节点的锁只能阻塞)
网友评论