[英]Assuring wait() is called before notify() in threading, is it possible?
当我遇到一个使用wait / notify方法的示例时,我正在看Kathy Sierra的书中的Threading一章:
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) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total += i;
}
notify();
}
}
}
运行代码始终会产生相同的输出:
等待b完成...总计为:4950
我通过添加以下内容修改了ThreadB中run()的同步块:
System.out.println("ThreadB is executed");
问题是:为什么我不断
“正在等待b完成...”
之前
“执行ThreadB”
? 线程b是否有可能在主线程之前执行?
线程b是否有可能在主线程之前执行?
是的,一点没错。
通常wait
会伴随一些谓词,以防止此类问题。
例如,ThreadB可以有一个变量,表示已完成。 您可以检查合计是否不为0。
synchronized (b) {
try {
System.out.println("Waiting for b to complete...");
while (b.total == 0) {
b.wait();
}
} catch (InterruptedException e) {
}
System.out.println("Total is: " + b.total);
}
相对于ThreadB中的写入,这会在total的读取上创建一个事前发生的关系。
线程b是否有可能在主线程之前执行?
是的,存在这种可能性,尽管对于狭窄的种族(如本段代码中的种族)而言,这种可能性很小。
该代码在获取b的监视器(同步块)之前调用b.start()
)。 在该窗口期间,主线程有可能被抢占,而线程B将首先运行并获取该监视器。
在这种情况下,该程序将挂起,因为主线程将永远wait()
因为它错过了线程B的notify()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.