为什么不调用通知等待释放锁定

时间:2014-03-28 10:41:50

标签: java multithreading

请参阅以下代码,其中注释了notifyAll。还有主线是打印总数吗?怎么可能?

public class ThreadA {
public static void main(String[] args){
    ThreadB b = new ThreadB();
    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: " + b.total);
    }
}}

class ThreadB extends Thread{
int total;
@Override
public void run(){
    synchronized(this){
        for(int i=0; i<100 ; i++){
            total += i;
        }
       // notify();
    }
}

}

3 个答案:

答案 0 :(得分:6)

您看到的是Thread.join()的javadoc中记录的内容的结果:

  

当一个线程终止时,将调用this.notifyAll方法。

请注意,它继续

  

建议应用程序不在线程实例上使用wait,notify或notifyAll

另请注意,由于虚假唤醒,wait()上阻塞的线程可能会在没有任何通知的情况下退出其等待状态。而wait()的javadoc清楚地解释了wait()应该始终在循环中调用。

答案 1 :(得分:0)

另请注意:Object.wait()的Java API文档说,&#34; ...中断和虚假唤醒是可能的,并且此方法应始终在循环中使用。&#34;

在其他API和其他语言中也是如此。方法/函数永远不应该假设它正在等待的条件是真的,因为对条件变量的wait()操作返回了。应该总是有一个循环。在伪代码中:

lock mutex
while (! ok_to_do_whatever()) {
    wait on condition_variable
}
do_whatever()
unlock mutex

答案 2 :(得分:-1)

试试这个,等待的线程将永远等待......

public class ThreadA {

    public static Object lock = new Object();

    public static void main(String[] args){
        ThreadB b = new ThreadB();
        b.start();

        synchronized(lock){
            try{
                System.out.println("Waiting for b to complete...");
                lock.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }

                System.out.println("Total is: " + b.total);
            }
        }
}

class ThreadB extends Thread
{
    int total;
    @Override
    public void run(){
        synchronized(ThreadA.lock){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            // notify();
        }
    }
}
相关问题