由同一对象同步的Wait-Notify不起作用

时间:2013-12-15 17:58:12

标签: java multithreading concurrency wait notify

我制作了这个样本,以了解Wait-Notify的工作原理:

public class WaitingTest implements Runnable {

    Thread b = new Thread();
    int total;

    public static void main(String[] args){
        WaitingTest w = new WaitingTest();
    }

    public WaitingTest(){
        b.start();
            synchronized(b){
                try{
                    System.out.println("Waiting for b to complete...");
                    b.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println("Total is: " + total);
            }
    }

    @Override
    public void run(){
        synchronized(b){
            for(int i=0; i<100 ; i++){
                total += i;
                System.out.println(total);
            }
            b.notify();
        }
    }
}

但是我被困在这里几个小时,我无法理解为什么它不能正常工作。我的输出应该大于0,但它总是为零......我想知道它是否因为使用不同的线程,但我不确定。我错过了什么?

2 个答案:

答案 0 :(得分:4)

我认为你的理解有一些严重的漏洞。您已声明Thread

Thread b = new Thread();

并在构造函数

中启动它
b.start();

Thread会立即开始并立即死亡,因为它没有附加Runnable

Thread死亡时,它会自行调用notify(),因为您synchronized对象Threadwait() Thread线程将被唤醒。你也在这里比赛。如果wait()在主线程到达run()之前结束,您将陷入僵局。

此外,没有理由调用total,这就是synchronized保持为0的原因。


任何对象都可以Thread开启,不一定是Thread。由于notify()具有Thread自身的奇怪行为,因此您可能不应该使用它。

您应该同时检查{{1}} tutorialssynchronization tutorials

答案 1 :(得分:1)

除了你如何安排你的线程的问题,你有一个错误的使用wait()/ notify()

notify()是无状态的。如果没有线程在等待,则不会通知任何内容。如果您稍后等待(),则不会收到通知。

wait()可以虚假地唤醒。仅仅因为wait()醒来并不意味着通知它。

这意味着您需要将wait / notify与state相关联(事实上,没有它就没有意义)

例如。

 // to notify
 synchronized(lock) {
     signalled = true;
     lock.notify();
 }

 // to wait
 synchronized(lock) {
     while(!signalled)
          lock.wait();
 }