簡體   English   中英

為什么此線程的行為如此奇怪?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM