2014-04-11 44 views
0

如果其他线程等待不同的条件,我们应该调用notifyAll(),这样每个其他线程都有机会获得执行。但是我们犯了一个错误,我们假设所有线程都在等待相同的条件,我们调用notify(),让JVM选择一个线程,但是选中的线程不能运行,因为条件仍然不能满足,那么会发生什么?当我们使用错误的notify()时会发生什么?

所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()一样?

+1

'但选中的线程无法运行,因为条件仍然不能满足请详细说明? –

+0

线程a:while(a> 0),线程b:while(b> 0),线程c:while(c> 0)... – lovespring

+0

'notify'唤醒已在该对象上调用wait的线程。这里没有什么可以满足的。 –

回答

1

JVM不能继续选择另一个线程来唤醒,因为重新输入wait的决定发生在更高级别的逻辑上,超出了线程调度程序的“时域”范围。所以是的,在你描述的场景中,所有的线程都会继续等待。

0

在这种情况下,您应该有一个deadlock,因为所有的线程都会停滞不前。

0
thread a: while(a>0), thread b: while(b>0), thread c: while(c>0) 

这是您的代码逻辑有缺陷。是的,这将导致deadlock。既然你有线程将继续吃掉你的CPU,并且因为它拥有锁定,所以其他线程无法获取它。

所有线程都停止运行?或者JVM继续选择另一个线程来唤醒,就像notifyALL()一样?

将获得关键区域锁定的线程将进入无限循环。所有其他线程将继续等待。只要某个线程持有该锁,任何JVM都不会通知其他线程。

0

所有等待同一监视器的线程都应等待循环中的相同条件成为true。通知()显示器的线程只能在使条件成立之后这样做。如果你遵循这些规则,那么至少有一个线程会醒来并能够取得进展。

E.g .;

final Object lock = new Object(); 
final AtomicBoolean timeToGo = new AtomicBoolean(false); 

Runnable waiter = new Runnable() { 
    public void run() { 
     synchronized(lock) { 
      while (! timeToGo.get()) { 
       lock.wait(); 
      } 
      System.out.println("Hello!"); 
      timeToGo.set(false); 
     } 
    } 
}; 

Runnable notifier = new Runnable() { 
    public void run() { 
     synchronized(lock) { 
      timeToGo.set(true); 
      lock.notify(); 
     } 
    } 
}; 

如果五个线程都挂在waiter.run()的wait()的方法,并且一个线程调用notifier.run(),然后正好五个一会打印“Hello!”并退出。其他人将继续等待下一个notifier.run()调用。当调用notifier.run()时,如果想让所有线程都打印hello,则将lock.notify()调用更改为lock.notifyAll(),并从waiter.run()中删除该行,即将标志设置为false。

相关问题