主题1:
if(!conditionFullfiled) this.wait();
主题2:
if(conditionFullfiled) thread1.notify();
我想从线程2中唤醒线程1,当某些条件已满。但是,当thread1.notify()
被调用if(!conditionFullfiled) ***HERE*** this.wait();
时,是不是有问题?
答案 0 :(得分:3)
要执行obj.wait()
和obj.notify()
,您需要拥有您要等待/通知的对象的监视器。在您的代码中,您可能不需要thread1.notify()。例如:
Object someSharedObject = ...
线程1:
synchronized(someSharedObject) {
// while NOT if for spurious wake ups.
while(!conditionFullfiled) someSharedObject.wait();
}
线程2:
synchronized(someSharedObject) {
if(conditionFullfiled) someSharedObject.notify(); // this wakes thread1
}
synchronized
锁定在someSharedObject
上(可以是this
),这意味着两个线程永远不会发生冲突。 .wait()
释放当前持有的监视器,因此当Thread1等待时不会阻止Thread2。
编辑:我学到了一些关于虚假唤醒的知识。 .wait()
必须在while
循环中完成 - if
是不够的。 Why do threads spontaneously awake from wait()?。感谢Enno Shioji教我。
修改:澄清.wait()
版本监控。
答案 1 :(得分:3)
这里有2个问题。
你不应该在线程对象本身上调用wait()和notify()。更好的方法是使用特殊的锁定对象,例如
private Object lock = new Object(); ...... lock.wait();
下一个问题是你必须同时调用wait()并通知同步块,即
同步(锁定){ //一些代码 lock.wait(); }
然后在代码中的其他地方说:
syncronized(lock) {
lock.notify(); // this line will cause the wait to terminate and the first thread to continue.
}
在一个类中本地化wait()
和notify()
包装方法很方便,因此可以访问锁定对象。
欲了解更多信息,请阅读 http://download.oracle.com/javase/6/docs/api/ http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html
答案 2 :(得分:0)
你用什么对象作为“这个”?如果你在thread1对象上调用wait(),你所显示的两个语句都包含在这样的循环中:
new Runnable() { synchronized (thread1) { thread1.wait() } }
然后您的代码将按您的意愿运行。 (当条件为假时,第一个线程将停止,否则将工作)。 诀窍是线程对象上的交互是同步的,因此一个线程不能中断而其他线程正在使用该对象。
编辑: 如果你不在线程上同步,而是在其他一些对象上同步(你可以简单地创建纯对象来提供锁定),那就更好了。
答案 3 :(得分:0)
完全没问题,因为等待释放对象锁定(如果是这样)。
保护while块中的等待/通知条件是最佳做法 - 避免虚假唤醒。