我期望以 7,100,1000 个乘法器的序列输出,有时显示但有时不显示。我不明白等待和通知的用法出了什么问题。
package com.facebook.dao;
public class ManyThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
targets target = new targets();
T1 x = new T1(target);
T2 y = new T2(target);
T3 z = new T3(target);
Thread t1 = new Thread(x);
Thread t2 = new Thread(y);
Thread t3 = new Thread(z);
t1.start();
t2.start();
t3.start();
}
}
class targets { boolean twoFlag = false; boolean threeFlag = true; boolean fiveFlag = true; int i = 7, j = 100, k = 1000; public synchronized void twoMul() { if (twoFlag) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(i * 2); threeFlag = false; twoFlag = true; notify();
}
public synchronized void threeMul() {
if (threeFlag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(j * 3);
fiveFlag = false;
threeFlag = true;
notify();
}
public synchronized void fiveMul() {
if (fiveFlag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(k * 5);
twoFlag = false;
fiveFlag = true;
notify();
}
}
class T1 implements Runnable { targets t;
T1(targets y) {
this.t = y;
}
public void run() {
for (int i = 0; i < 3; i++) {
t.twoMul();
}
}
}
class T2 implements Runnable {
targets t;
T2(targets y) {
this.t = y;
}
public void run() {
for (int i = 0; i < 3; i++) {
t.threeMul();
}
}
}
class T3 implements Runnable { targets t;
T3(targets y) {
this.t = y;
}
public void run() {
for (int i = 0; i < 3; i++) {
t.fiveMul();
}
}
}
我认为我正确地使用了标志,但我想知道哪里出了问题。
最佳答案
notify()
通知等待线程中的一个。因此,在 T1 任务调用 notify()
后,T2 或 T3 将唤醒并继续其任务。
请注意,您并不是在循环检查条件。您正在使用 if
。因此,一旦线程重新启动,它就会跳出 if block 并继续。
顺便说一句,即使那是意图,它也不遵循 documentation of wait()
中描述的规则。 : 可能会发生虚假唤醒,并且应始终在循环内调用 wait 并在退出等待状态之前检查条件。
所以
- 使用循环代替
if
- 使用
notifyAll()
代替notify()
关于java - 多线程通信为什么使用等待和通知不能保证输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22730006/