请参阅以下代码,其中注释了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();
}
}
}
答案 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();
}
}
}