主题1:简单的Java并发问题
if(!conditionFullfiled) this.wait();
线程2:
if(conditionFullfiled) thread1.notify();
我想从线程2唤醒线程1,当一些条件fullfiled。但是,当thread1.notify()
被称为if(!conditionFullfiled) ***HERE*** this.wait();
时,是不是有问题?
主题1:简单的Java并发问题
if(!conditionFullfiled) this.wait();
线程2:
if(conditionFullfiled) thread1.notify();
我想从线程2唤醒线程1,当一些条件fullfiled。但是,当thread1.notify()
被称为if(!conditionFullfiled) ***HERE*** this.wait();
时,是不是有问题?
要做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
}
的锁定时someSharedObject
(可以是this
),这意味着这两个线程将永远不会发生冲突。 .wait()
释放当前保持的监视器,因此当Thread1正在等待时,线程2不会被阻塞。
编辑:我学到了一些关于虚假唤醒的知识。 .wait()
必须在while
循环中完成 - if
是不够的。 Why do threads spontaneously awake from wait()?。谢谢Enno Shioji教我。
编辑:澄清.wait()
版本监测。
你用什么对象作为“this”?如果调用wait()的线程1对象上,你表现出的语句都被包裹在这样的循环:
new Runnable() { synchronized (thread1) { thread1.wait() } }
那么你的代码将工作,只要你想。 (当条件为false时,第一个线程将停止,否则工作)。 诀窍是线程对象上的交互是同步的,因此一个线程不能在其他人使用该对象时中断。
编辑: 如果您不是在线程上进行同步,而是在某个其他对象(您可以简单地创建纯对象以提供锁定)上进行同步,那将会更好。
因为等待释放对象锁定(在这种情况下)完全没问题。
这是防止等待/通知条件的最佳做法,以避免虚假的唤醒。
这里有2个问题。
你不应该在线程对象本身上调用wait()和notify()。更好的方法是使用特殊的锁定对象,例如
private Object lock = new Object(); ...... lock.wait();
接下来的问题是,必须调用二者wait()和通知到synchornized块,即
syncronized(锁){// 一些代码 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
`if`应该`while`被替换应付虚假的起床。 – 2010-11-28 12:38:03