Java notify()在wait()之前运行? [英] Java notify() run before wait()?
问题描述
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();
}
}
}
如上例所示,如果 wait()
阻止先输入,ThreadB中的后续 notify()
将告诉主线程继续。
As the example above, if wait()
block enter first, the subsequent notify()
in ThreadB will tell the Main Thread to continue.
但我们不能保证 wait()
将在 notify($ c)之前执行$ c>),如果ThreadB首先进入块怎么办?
Notify()
将在 wait()
之前执行,所以 wait()
将永远挂在那里(因为没有更多 notify()
告诉它继续)?什么通常是处理这个的正确方法?
But we cannot guarantee wait()
will execute before notify(
), what if ThreadB enter the block first? Notify()
will execute before wait()
, so wait()
will hang there forever (because no more notify()
to tell it to continue)? What usually is the proper way to handle this?
推荐答案
你应该几乎总是有一个谓词和wait / notify。也就是说,你需要一个可以检查的条件
,例如变量变为真,队列变空/满等等。只是盲目地等待某人调用.notify()只有很少的用例。
You should almost always have a predicate together with wait/notify. That is, you need a condition that you can check, such as a variable becoming true, a queue becoming empty/full etc. Just blindly waiting for someone to call .notify() have very few use cases.
所以,以下是不行的,因为你说的原因,另一个线程可以在ThreadA调用之前调用.notify()。等于()
So, The following is Not OK, for the reason you say, the other thread could call .notify() before ThreadA calls .wait()
public class ThreadA {
public static Object latch = new Object();
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(latch ) {
latch.wait(); //wait for B to finish a calculation
}
System.out.println("Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
total += i;
}
synchronized(ThreadA.latch) {
ThreadA.latch.notify();
}
}
}
你需要做类似的事情这个:
You need to do something like this:
public class ThreadA {
public static Object latch = new Object();
public static boolean done = false;
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(latch ) {
while (!done) { //wait for B to indicate it is finished.
latch.wait();
}
}
System.out.println("Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
total += i;
}
synchronized(ThreadA.latch) {
ThreadA.done = true;
ThreadA.latch.notify();
}
}
}
请注意,在上面, done
变量受同步块保护, .wait()
将自动释放/重新获取该锁定。所以没有竞争条件,如果在我们到达 .wait()
之前调用.notify(),ThreadA会发现因为完成
将 true
,并且根本不输入 .wait()
。
Note that in the above, the done
variable is protected by the synchronized block, .wait()
will atomically release/re-aquire that lock. So there is no race condition, and if .notify() is called before we get to the .wait()
call , ThreadA will discover that because done
will be true
and not enter the .wait()
call at all.
对于一个简单的例如此代码的情况,你可以等待ThreadB结束,可以用 b.join();
For a simple case such as this code, you can just wait for ThreadB to to end, can be done with b.join();
这篇关于Java notify()在wait()之前运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!