Java notify()在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()先进入块,则notify()ThreadB中的后续块将告诉主线程继续。

但是我们不能保证wait()将在notify()之前执行,如果ThreadB首先进入该块怎么办?Notify()会在之前执行wait(),所以wait()会永远挂在那里(因为不再notify()告诉它继续执行)?通常有什么合适的方法来解决这个问题?

回答:

您几乎应该总是将谓词与等待/通知一起使用。也就是说,您需要可以检查的条件,例如变量变为true,队列变为空/满等。仅盲目地等待某人调用.notify()的用例很少。

因此,以下内容并不正确,由于您所说的原因,另一个线程可以在ThreadA调用.wait()之前调用.notify()。

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();

}

}

}

您需要执行以下操作:

 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会发现原因done是,因为将存在true且根本没有进入该.wait()调用。

对于这种代码这样的简单情况,您可以等待ThreadB结束,可以通过 b.join();

以上是 Java notify()在wait()之前运行? 的全部内容, 来源链接: utcz.com/qa/415077.html

回到顶部