Java多线程令人困惑的代码片段

时间:2013-11-18 17:07:30

标签: java multithreading

如果在不同时间随机执行,下面的代码应如何执行?

public class Unstoppable extends Thread {
    private int counter;

    @Override
    public void run() {
        synchronized(this) {
            for(int i = 0; i < 10; i++)
                counter++;

            this.notifyAll();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Unstoppable unStoppable = new Unstoppable();

        System.out.println("I am about to start");
        unStoppable.start();
        synchronized(unStoppable) {
            System.out.println("I was just told to wait");
            unStoppable.wait();
        }

        System.out.println(unStoppable.counter);
    }
}

第一眼看到它似乎它会无限地悬挂但是每次执行此操作时都会惊讶地发现它......它完成了执行。

3 个答案:

答案 0 :(得分:2)

如果您有两个或更多线程,则同步很有意义。在你的情况下,只有一个线程。

 public static void main(String[] args) throws InterruptedException {
    Unstoppable unStoppable = new Unstoppable();
    Unstoppable unStoppable2 = new Unstoppable();
    Unstoppable unStoppable3 = new Unstoppable();
    System.out.println("I am bout to start");
    unStoppable.start();
    unStoppable2.start();
    unStoppable3.start();
    synchronized (unStoppable) {
        System.out.println("I was just told to wait");
        unStoppable.wait();
    }

    System.out.println(unStoppable.counter);
}

}

随机执行此操作,它可能会等待或尝试增加线程数。顺便说一下wait应该像这样实现。

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
  }

答案 1 :(得分:0)

你是否以某种方式忽略了例外......代码:

// synchronized(unstoppable) {
    System.out.println("I was just told to wait forever");
    unstoppable.wait();
// }

应抛出IllegalMonitorStateException并立即退出。


修改

所以你改变了你的代码,现在它按你期望的方式工作(它永远等待),那么问题是什么? (我刚试过它)。

答案 2 :(得分:0)

  

第一次看这个时,似乎它会无限地悬挂,但每次执行时都会令人惊讶......它完成了执行。

完成,因为当Thread完成时,会有thread.notify()的幕后调用。这就是thread.join()的实施方式。

也就是说,依赖于以这种方式工作的代码并不是一个好主意 - 或者至少应该被标记为黑客。您应该使用thread.join()代替:

unStoppable.join();

最后,您应该考虑使用Unstoppable类实现Runnable而不是扩展线程。这是一个更好的模式:

public class Unstoppable implements Runnable {
...

Thread unStoppableThread = new Thread(new Unstoppable());
...
unStoppableThread.join();