开发者

Why does this Thread behave so strange?

开发者 https://www.devze.com 2023-02-19 16:32 出处:网络
Let\'s think of following code fragment, that behaves as expected. Thread runs, then it\'s paused and then it\'s unpaused and finishes it\'s execution:

Let's think of following code fragment, that behaves as expected. Thread runs, then it's paused and then it's unpaused and finishes it's execution:

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
    }

Now let's add add some sleeping to thread so it's paused for a while:

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
    }

But that code never finishes. Why ?

Here's implementation of pause method, it checks private boolean field for pausing:

public synchronized void pause() {
        paused = (paused) ? false : true;
    }

And here is implementation of overriden run method:

@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 ope开发者_C百科ration
            }
        }
        System.out.println("I'm done");
    }

private void checkPause() {
        synchronized (this) {
            if (paused) {
                while (paused != false) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

When I tried debugging, I'll end on wait() method. Then it just waits :/


When you call wait(), your thread waits until another thread calls its notify() method.

You're not calling notify() on the thread from your main thread.

Also note that synchronize(this) is the same thing as synchronizing the method; it's using the object itself as the lock. Once your thread hits wait() your main thread will block on thread.unpause() because the checkPause() method has the lock.


I see the wait(), but I don't see the corresponding notify() call that would wake the thread again.


I think that in the 1st case, the thread doesn't pause at all, because if there is no Thread.sleep(500);, probably both pause() are called before checkPause() and the Thread never waits. In the 2nd case, the thread reaches checkPause() when pause = true and the it waits. since no one call notify(), it will not continue.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号