您的位置:首页 > 其它

【CountDownLatch】死循环检测模板/多线程重复测试模板

2017-05-23 23:36 357 查看
意义:

CountDownLatch的一个作用是检测死循环,因为死循环不容易复现,需要把一个程序执行多次。

有的同学会用脚本循环执行,如果没有linux环境,还得装环境,有点麻烦。

所以想到直接用Java实现重复执行一段代码的功能。

注意:

0、其实,HashMap的死循环不好复现,且没什么实际意义。并发本身就是会出各种各样的问题,本文的价值更多体现在怎么用JMC查看死循环,以及怎么用模板循环测试代码片段。

1、JDK1.8在TreeNode.split()中死循环

2、MapOper中的for循环,次数要设置大一些,设置为100,基本复现不了,设置为50000,到61就复现了。

3、put操作进行try catch,因为并发操作经常出现exception,中断循环,阻碍死循环的复现。

结果如下:

LoopTime: 6217

LoopTime: 6218

LoopTime: 6219

LoopTime: 6220 --》卡在这

有时候会报内存泄漏错误

Exception in thread "Thread-124" java.lang.OutOfMemoryError: Java heap space
at java.util.HashMap.replacementNode(Unknown Source)
at java.util.HashMap$TreeNode.untreeify(Unknown Source)
at java.util.HashMap$TreeNode.split(Unknown Source)
at java.util.HashMap.resize(Unknown Source)
at java.util.HashMap.putVal(Unknown Source)
at java.util.HashMap.put(Unknown Source)
at multithread.CountDownLatchForInfinitLoop$MapOper.run(CountDownLatchForInfinitLoop.java:47)
at java.lang.Thread.run(Unknown Source)

可能因为resize()一直在循环,导致某些对象不能回收,最终内存泄漏,这块具体还没分析。

用jmc.exe工具(在JDK的bin目录下)可以看到,线程堆栈一直停在split()方法了,说明这里有死循环



CountDownLatch在本例子的作用是,每次Loop都等线程执行完了,再执行下一次loop,如果某一次出现死循环,则countDown()不会被执行,loop就会被hang在某次循环。

本篇是在:【CountDownLatch实例】主线程等待其它线程执行完毕 的基础之上进行修改的

参考:hashmap死循环示例及检测方法。 

---------------------------------------------

package multithread;

import java.util.HashMap;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchForInfinitLoop {

public static void loopOper() throws InterruptedException{
CountDownLatchForInfinitLoop test = new CountDownLatchForInfinitLoop();

CountDownLatch latch = new CountDownLatch(2);
HashMap map = new HashMap(2);

Thread t1 = new Thread(test.new MapOper(latch,map));
Thread t2 = new Thread(test.new MapOper(latch,map));

/*	t1.setName("Thread1");
t2.setName("Thread2");*/
t1.start();
t2.start();
latch.await();
}

public static void main(String[] args) throws InterruptedException {

for (int i = 0; i < 1000000; i++) {
loopOper();
System.out.println("LoopTime: "+i);
}

}

public class MapOper implements Runnable {

CountDownLatch latch ;
HashMap map;
int i;

public MapOper(CountDownLatch latch, HashMap map) {
this.latch = latch;
this.map = map;
this.i = i;
}

public void run() {

for (int i = 0; i < 50000; i++) {
try {

map.put(String.valueOf(i),i);
} catch (Exception e) {
System.out.println("put value exception");
}
}

latch.countDown();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息