【发布时间】:2020-12-29 23:22:29
【问题描述】:
我的目标是一个线程打印奇数,另一个线程打印偶数。 下面的实现显示了奇怪的输出。请让我知道我在这段代码中缺少什么。
它按预期打印 0 和 1。然后打印 3 和 2。
// 预期 -> 012345678910
//此代码实际输出-> 013254769810(流量正在变化)
public class OddEvenNumberPrint {
public static boolean state = false; // based on this flag I will wait or notify
public static Object lock = new Object(); // the common locking object
public static void main(String[] args) {
EvenThread t1 = new EvenThread("Even");
t1.start();
OddThread t2 = new OddThread("Odd");
t2.start();
}
}
class EvenThread extends Thread {
public EvenThread(String name) {
this.setName(name);
}
public void run() {
for (int i = 0; i <= 10; i = i + 2) {
synchronized (OddEvenNumberPrint.lock) {
System.out.println("Even ->"+i);
while (!OddEvenNumberPrint.state) {
try {
System.out.println(Thread.currentThread().getName()+ " : "+ "Going wait");
OddEvenNumberPrint.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
OddEvenNumberPrint.state = false;
OddEvenNumberPrint.lock.notify();
System.out.println(Thread.currentThread().getName()+ " : "+ "Released");
}
}
}
}
class OddThread extends Thread {
public OddThread(String name) {
this.setName(name);
}
public void run() {
for (int i = 1; i < 10; i = i + 2) {
synchronized (OddEvenNumberPrint.lock) {
System.out.println("Odd -> "+i);
while (OddEvenNumberPrint.state) {
try {
System.out.println(Thread.currentThread().getName()+ " : "+ "Going wait");
OddEvenNumberPrint.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
OddEvenNumberPrint.state = true;
OddEvenNumberPrint.lock.notify();
System.out.println(Thread.currentThread().getName()+ " : "+ "Released");
}
}
}
}
输出:
Even ->0
Even : Going wait
Odd -> 1
Odd : Released
Odd -> 3
Odd : Going wait
Even : Released
Even ->2
Even : Going wait
Odd : Released
Odd -> 5
Odd : Going wait
Even : Released
Even ->4
Even : Going wait
Odd : Released
Odd -> 7
Odd : Going wait
Even : Released
Even ->6
Even : Going wait
Odd : Released
Odd -> 9
Odd : Going wait
Even : Released
Even ->8
Even : Going wait
Odd : Released
Even : Released
Even ->10
Even : Going wait
【问题讨论】:
-
请解释您认为输出“奇怪”的地方,以及您认为它奇怪的原因。另请解释您的预期。
-
你期待什么输出?!!
-
1.提示:您的程序不会终止。 (在可接受的期限内) 2. 提示:不要使用局部变量进行计数,而是使用“同步”变量。
-
@MarkRotteveel 和 Omid,我已经给出了正确的细节。
-
没有什么能阻止奇数循环打印 1,然后在偶数线程再次轮到它之前打印 3。如果您想要您期望的顺序,您可能需要将
state初始化为true,并将值的打印移动到循环之后(尽管我没有仔细查看)。您似乎期望notify()会立即给另一个线程运行的机会,但事实并非如此。
标签: java multithreading synchronization thread-safety wait