public class StopMultiThread {
private static boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
int testNum = 100;
List<Boolean> result = new ArrayList<>(testNum);
CountDownLatch countDownLatch = new CountDownLatch(testNum);
for (int i = 0; i < testNum; i++) {
int copy = i;
Thread backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
long beginTime = System.currentTimeMillis();
int j = 0;
while (!stopRequested) {
// j++;
System.out.println("brokenStopMultiThread " + copy + " " + j++);
}
long runTime = System.currentTimeMillis() - beginTime;
System.out.println("brokenStopMultiThread " + copy + " run " + runTime);
result.add(runTime < 1500);
countDownLatch.countDown();
}
});
backgroundThread.start();
}
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
countDownLatch.await();
System.out.println("result:" + result);
int expectedTimes = 0;
for (Boolean b : result)
if (b)
expectedTimes++;
System.out.println("expectedTimes:" + expectedTimes + ", brokenTimes:" + (result.size() - expectedTimes));
}
}
环境
java版“1.8.0_77”
Java(TM)SE运行时环境(版本1.8.0_77-b03)
Java HotSpot(TM)64位服务器VM(内置25.77-b03,混合模式)
上面的代码可以正常停止线程,但下面的代码不能,为什么?
while (!stopRequested) {
j++;
// System.out.println("brokenStopMultiThread " + copy + " " + j++);
}
测试5次
代码A将导致
expectedTimes:23,brokenTimes:977
expectedTimes:45,brokenTimes:955
expectedTimes:174,brokenTimes:825
expectedTimes:207,brokenTimes:793
expectedTimes:175,brokenTimes:825
代码A
while (!stopRequested) {
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
// System.out.println("brokenStopMultiThread " + copy + " " + j++);
}
代码B将导致
expectedTimes:1000,brokenTimes:0
expectedTimes:999,brokenTimes:0
expectedTimes:1000,brokenTimes:0
expectedTimes:1000,brokenTimes:0
expectedTimes:1000,brokenTimes:0
代码B
while (!stopRequested) {
/*try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;*/
System.out.println("brokenStopMultiThread " + copy + " " + j++);
}
所有线程都以不同的runTime停止,也许在jdk8上不会轻易发生活动失败