繁体   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