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 中的 ThreadB 会告诉主线程继续。
但我们不能保证wait()
将在之前执行notify(
),如果ThreadB先进入块怎么办?Notify()
将在之前执行wait()
, so 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()
将自动释放/重新获取该锁。所以不存在竞争条件,并且如果在我们到达之前调用 .notify().wait()
调用 , ThreadA 会发现因为done
将true
并且不输入.wait()
根本不打电话。
对于像这段代码这样的简单情况,您可以等待 ThreadB 结束,可以使用b.join();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)