资讯专栏INFORMATION COLUMN

HashMap的死循环

HelKyle / 946人阅读

摘要:并发的为什么会引起死循环在多线程使用场景中,应该尽量避免使用线程不安全的,而使用线程安全的。那么为什么说是线程不安全的,下面举例子说明在并发的多线程使用场景中使用可能造成死循环。注意此时两个线程已经成功添加数据。

并发的HashMap为什么会引起死循环?

在多线程使用场景中,应该尽量避免使用线程不安全的 HashMap,而使用线程安全的 ConcurrentHashMap。那么为什么说 HashMap 是线程不安全的,下面举例子说明在并发的多线程使用场景中使用 HashMap 可能造成死循环。代码例子如下(便于理解,仍然使用 JDK1.7 的环境):

public class HashMapInfiniteLoop {  

    private static HashMap map = new HashMap(2,0.75f);  
    public static void main(String[] args) {  
        map.put(5, "C");  

        new Thread("Thread1") {  
            public void run() {  
                map.put(7, "B");  
                System.out.println(map);  
            };  
        }.start();  
        new Thread("Thread2") {  
            public void run() {  
                map.put(3, "A);  
                System.out.println(map);  
            };  
        }.start();        
    }  
}

其中,map初始化为一个长度为2的数组,loadFactor=0.75,threshold=2*0.75=1,也就是说当put第二个key的时候,map就需要进行resize。

通过设置断点让线程1和线程2同时debug到transfer方法(3.3小节代码块)的首行。注意此时两个线程已经成功添加数据。放开thread1的断点至transfer方法的“Entry next = e.next;” 这一行;然后放开线程2的的断点,让线程2进行resize。结果如下图。

注意,Thread1的 e 指向了key(3),而next指向了key(7),其在线程二rehash后,指向了线程二重组后的链表。

线程一被调度回来执行,先是执行 newTalbe[i] = e, 然后是e = next,导致了e指向了key(7),而下一次循环的next = e.next导致了next指向了key(3)。

e.next = newTable[i] 导致 key(3).next 指向了 key(7)。注意:此时的key(7).next 已经指向了key(3), 环形链表就这样出现了。

于是,当我们用线程一调用map.get(11)时,悲剧就出现了——Infinite Loop。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74393.html

相关文章

  • 一起读源码之 — HashMap(jdk1.7)

    摘要:关于不安全的问题,感兴趣的可以去看一下这篇文章老生常谈,的死循环。 废话不多说,直接进入主题: 首先我们从构造方法开始: public HashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); } public HashMap(int initialCapacity, f...

    ASCH 评论0 收藏0
  • 2016-11-17遇到的死循环

    摘要:今天在复制代码时,遇到死循环,导致在里面执行没有反应其中第二个循环是直接粘贴的,其中的忘记修改,正确的代码是后续应该避免犯这个错误 今天在复制代码时,遇到死循环,导致在 Console 里面执行没有反应: var s = [] var newA = unique(a) var newB = unique(b) for (var i = 0; i < ne...

    PascalXie 评论0 收藏0
  • WordPress 使用钩子进行主题开发时避免死循环

    摘要:开发时,我们经常会使用或等钩子,以便在更新文章或分类时,增加一些附加数据,这些钩子触发的时机是发布或更新数据的时间,如果处理不好,就会出现死循环的情况,导致更新数据时出现死循环的情况。我们可以做的是在开发过程中尽量小心,避免死循环的出现。 WordPress 开发时,我们经常会使用 save_post 或 create_post_tag 等钩子,以便在更新文章或分类时,增加一些附加数据...

    LeexMuller 评论0 收藏0

发表评论

0条评论

HelKyle

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<