HashMap在并发环境下发生死循环
2016-09-20 14:36
225 查看
HashMap不是线程安全的,在高并发的某种情况下会发生死循环,主要是在HashMap扩容时的 transfer方法出现了问题:
两个线程P1和P2都走到这个方法,执行方法前链表数据如下:
P1:a->b->c->d->null
P2:a->b->c->d->null
线程按一下顺序执行:
1. P1第一次执行到(1)处时阻塞,此时 next 的值是b ,e的值是a;
2. P2执行完整个流程,此时链表在newTable中可能变成如下情况:
b->a
c
d
3. P1继续执行,以下代码中newTable[i]是P2执行完的链表第一个元素b,执行完以下代码会导致a->b,而在新的一轮循环中,b.next是a,死循环产生;
死循环产生的必要条件(欢迎指正):
1. 原索引数组的某个链表中的有两个元素A,B相邻
2. A,B被转到新的索引数组的同一个链表,即索引值相同
3. 高并发
/** * Transfers all entries from current table to newTable. */ 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 { Entry<K,V> next = e.next;//(1) int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); } } }
两个线程P1和P2都走到这个方法,执行方法前链表数据如下:
P1:a->b->c->d->null
P2:a->b->c->d->null
线程按一下顺序执行:
1. P1第一次执行到(1)处时阻塞,此时 next 的值是b ,e的值是a;
2. P2执行完整个流程,此时链表在newTable中可能变成如下情况:
b->a
c
d
3. P1继续执行,以下代码中newTable[i]是P2执行完的链表第一个元素b,执行完以下代码会导致a->b,而在新的一轮循环中,b.next是a,死循环产生;
e.next = newTable[i]; newTable[i] = e;
死循环产生的必要条件(欢迎指正):
1. 原索引数组的某个链表中的有两个元素A,B相邻
2. A,B被转到新的索引数组的同一个链表,即索引值相同
3. 高并发
相关文章推荐
- 在并发环境下使用HashMap导致的线程死循环问题
- HashMap在并发环境下的死循环分析
- Java在并发情况下使用HashMap造成死循环
- Java中的HashMap源码记录以及并发环境的几个问题
- Java集合---多线程环境下hashmap死循环
- Java面试题:高并发环境下,HashMap可能出现的致命问题。注意:是在jdk8以下版本
- 一个由于数据库并发引起的错误,开发环境里一切都正常、运行环境里不稳定、发生莫名奇妙的错误
- 《Java困惑》:多并发情况下HashMap是否还会产生死循环
- 一个由于数据库并发引起的错误,开发环境里一切都正常、运行环境里不稳定、发生莫名奇妙的错误
- HashMap在高并发下引起的死循环
- 一个由于数据库并发引起的错误,开发环境里一切都正常、运行环境里不稳定、发生莫名奇妙的错误
- 并发环境下HashMap引起的full gc排查
- 并发的HashMap为什么会引起死循环
- 一个由于数据库并发引起的错误,开发环境里一切都正常、运行环境里不稳定、发生莫名奇妙的错误
- 并发场景下HashMap死循环导致CPU100%的问题
- 多线程环境下HashMap之死循环
- 高并发环境下低级死循环bug
- hashMap并发环境下存在隐患
- 推荐:并发情况下:Java HashMap 形成死循环的原因
- 漫画:高并发下的HashMap引起的链表死循环原因分析