hashmap线程安全问题
-在单线程情况下,由于不存在另外一个进程去读取程序,故而不可能发生代码在逻辑上的判定失常;多线程则体现在以下2个方面
- 当进行扩容操作的时候,会执行如下代码
void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<K,V> e = src[j];
if (e != null) {
src[j] = null;
do {
q: Entry<K,V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
在整个时候由于代码执行到标记q处,就被cpu夺取了执行权,而别的线程在此情况下,执行完全部的代码之后;原来的线程会从q处依旧继续执行下去,导致hashmap桶中的最后一个元素又插入到头结点,使得该节点又指向‘指向他的节点从而形成死循环’
2、上述是发生在扩容,如下发生在多线程put操作
第一种情况是发生在扩容时候的开始节点,而多线put操作导致线程安全是在原本链表的后端部分
当处在不同桶中的元素的next是null的时候,会导致原本另外一个线程,在原本的链表中找不到后续的节点,而错判需要put的元素已经全部完成,导致的后面不同桶中的元素的丢失