当前位置:   article > 正文

Java集合-HashMap1.8也会发生死循环_.java1.8还会出现死循环吗?

.java1.8还会出现死循环吗?

在网上搜资料时候然后发现网上都说1.7版本的HashMap会发生死链也就是死循环,但是在HashMap中也会产生死循环,接下来直接看代码吧

代码

类名字我忘记改了这是我以前看park时候弄的但是这不重要

当你运行

public class parkAndUnpark {
    static  Map<String,String> map = new HashMap<>();
    static class MyTask implements Runnable{
        int start = 0;
        public MyTask(int start){
            this.start = start;
        }
        @Override
        public void run() {
            for(int i = start ; i<10000000;i+=2){
                map.put(Integer.toString(i),Integer.toBinaryString(i));
                System.out.println(i);
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new MyTask(0));
        Thread t2 = new Thread(new MyTask(1));
        t1.start();
        t2.start();
        //主线程等待两个线程执行完
        t1.join();
        t2.join();
        System.out.println(map.size());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

好了这里会阻塞住
但是可能你没阻塞住所以多运行几次

在这里插入图片描述

实验jps查看运行线程

在这里插入图片描述

jstack

使用jstack分析堆栈快照

在这里插入图片描述

两个线程都在运行但是没有输出同时也没有结束这就产生了死循环,所以分析

分析

分析balanceInsertion 方法,上面就可以看到

 static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
                                             TreeNode<K,V> x) {
     //新插入的节点标为红色
     x.red = true;
     
     //无限for循环,定义xp、xpp、xppl、xppr变量,在循环体进行赋值,p就是parents
     //- root:当前根节点
     //- x   :新插入的节点
     //- xp  :新插入节点的父节点
     //- xpp :新插入节点的祖父节点
     //- xppl:新插入节点的左叔叔节点
     //- xppr:新插入节点的右叔叔节点
     for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
     	 
     	 //为定义的各个变量赋值的过程
         if ((xp = x.parent) == null) {
             x.red = false;
             return x;
         }
         else if (!xp.red || (xpp = xp.parent) == null)
             return root;
         //重点看这里
         //如果父节点是爷爷节点的左孩子
         if (xp == (xppl = xpp.left)) {
         	 //如果右叔叔不为空且为红色
             if ((xppr = xpp.right) != null && xppr.red) {
             	 //右叔叔变为黑色
                 xppr.red = false;
                 //父节点变为黑色
                 xp.red = false;
                 //爷爷节点变为黑色
                 xpp.red = true;
                 //将爷爷节点当作起始节点,再次循环,请注意再次循环!!!
                 x = xpp;
             }
		//省略其他代码
 }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

总的来说上边的源码就是,新插入一个节点,该方法要保持红黑树的五个性质

性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的路径上包含的黑色节点数量都相同。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/576451
推荐阅读
相关标签
  

闽ICP备14008679号