我制作了这个样本,以了解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,但它总是为零......我想知道它是否因为使用不同的线程,但我不确定。我错过了什么?
答案 0 :(得分:4)
我认为你的理解有一些严重的漏洞。您已声明Thread
Thread b = new Thread();
并在构造函数
中启动它b.start();
Thread
会立即开始并立即死亡,因为它没有附加Runnable
。
当Thread
死亡时,它会自行调用notify()
,因为您synchronized
对象Thread
,wait()
Thread
线程将被唤醒。你也在这里比赛。如果wait()
在主线程到达run()
之前结束,您将陷入僵局。
此外,没有理由调用total
,这就是synchronized
保持为0的原因。
任何对象都可以Thread
开启,不一定是Thread
。由于notify()
具有Thread
自身的奇怪行为,因此您可能不应该使用它。
您应该同时检查{{1}} tutorials和synchronization 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();
}