public class Test {
public static Object object = new Object();
public static boolean printA = true;
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
threadA.start();
ThreadB threadB = new ThreadB();
threadB.start();
}
}
class ThreadA extends Thread {
@Override
public void run() {
for(int i = 0; i < 10; i++) {
synchronized (Test.object) {
if(!Test.printA) {
try {
Test.object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("A");
Test.printA = false;
Test.object.notify();
}
}
}
}
}
class ThreadB extends Thread {
@Override
public void run() {
for(int i = 0; i < 10; i++) {
synchronized (Test.object) {
if(Test.printA) {
try {
Test.object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("B");
Test.printA = true;
Test.object.notify();
}
}
}
}
}
运行以上代码,为什么会一直不结束无限wait下去?
------------------ 分割线,以下是正确的写法 -------------------
实际上线程中不应该有else,把else注释掉就正确了。 如果加上else后,该线程会在wait后不再notify,导致另一个线程无限wait。
public class Test {
public static Object object = new Object();
public static boolean printA = true;
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
threadA.start();
ThreadB threadB = new ThreadB();
threadB.start();
}
}
class ThreadA extends Thread {
@Override
public void run() {
for(int i = 0; i < 10; i++) {
synchronized (Test.object) {
if(!Test.printA) {
try {
Test.object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}/* else {*/
System.out.println("A");
Test.printA = false;
Test.object.notify();
/*}*/
}
}
}
}
class ThreadB extends Thread {
@Override
public void run() {
for(int i = 0; i < 10; i++) {
synchronized (Test.object) {
if(Test.printA) {
try {
Test.object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}/* else { */
System.out.println("B");
Test.printA = true;
Test.object.notify();
/*}*/
}
}
}
}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
帮你的代码加了点注释,同时把i缩小到4,这样好分析点。你执行一遍然后看看输出的日志你就知道问题在哪了。
其实问题就是A执行完了,B正好处于wait状态,以至于没有人来notify他,你可以直接给A多循环一次即可。
这个和生产者消费者的问题很像。你题目中无限
wait下去唯一的情况是:当ThreadA或ThreadB有一方已执行完,未执行完的线程wait之后,另一线程并不能唤醒它,因为那个线程已跑完了。A线程先跑,如果B还没有wait的时候,A已经notify了,这时这个notify就没有效果,等B开始wait了,A的notify已经跑完了,根本永远得不到通知,你这么写逻辑是有问题的
很明显ThreadB先wait,但代码却ThreadA先调用.... 只要让ThreadB先执行就可以了