[英]Why java thread behave so differently if they shouldnt in this scenario?
[英]Why does this Thread behave so strange?
让我们考虑以下代码片段,其行为符合预期。 线程运行,然后暂停,然后取消暂停并完成执行:
public static void main(final String[] args) throws InterruptedException {
Executor exec = Executors.newSingleThreadExecutor();
MyThread thread = new MyThread();
exec.execute(thread);
thread.pause();
thread.pause(); // unpause
}
现在让我们添加一些睡眠到线程,以便暂停一会儿:
public static void main(final String[] args) throws InterruptedException {
Executor exec = Executors.newSingleThreadExecutor();
MyThread thread = new MyThread();
exec.execute(thread);
thread.pause();
Thread.sleep(500);
thread.pause(); // unpause
}
但是该代码永远不会完成。 为什么呢
这是pause方法的实现,它检查私有布尔字段是否暂停:
public synchronized void pause() {
paused = (paused) ? false : true;
}
这是重写运行方法的实现:
@Override
public void run() {
// don't worry, I just need som dummy data to take some cpu time ;)
PriorityQueue<Double> queue = new PriorityQueue<Double>();
Random random = new Random(System.currentTimeMillis());
System.out.println("I stared");
checkPause();
// let's do some big computation
for (int i=0; i<10000000; i++) { // 10 mio
System.out.println(i);
queue.add(random.nextDouble());
if (i % 3 == 0) {
queue.poll(); // more complex operation
}
}
System.out.println("I'm done");
}
private void checkPause() {
synchronized (this) {
if (paused) {
while (paused != false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
当我尝试调试时,我将以wait()
方法结束。 然后它只是等待:/
当您调用wait()
,您的线程将等待,直到另一个线程调用其notify()
方法。
您不是从主线程在线程上调用notify()
。
还要注意, synchronize(this)
与同步方法相同; 它使用对象本身作为锁。 一旦您的线程达到了wait()
您的主线程将在thread.unpause()
上thread.unpause()
因为checkPause()
方法已锁定。
我看到了wait()
,但是没有看到相应的notify()
调用,它将再次唤醒线程。
我认为在第一种情况下,线程根本不会暂停,因为如果没有Thread.sleep(500);
,可能两个pause()
在checkPause()
之前都被调用,并且线程从不等待。 在checkPause()
情况下,线程在pause = true时到达checkPause()
,并且它等待。 由于没有人调用notify()
,因此它将不会继续。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.