![](/img/trans.png)
[英]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.