赞
踩
在网上搜资料时候然后发现网上都说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()); } }
好了这里会阻塞住
但是可能你没阻塞住所以多运行几次
使用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 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的路径上包含的黑色节点数量都相同。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。