我试图使用两个不同的线程打印偶数和奇数。有人可以指出我犯的错误。 目前这是输出的样子:
奇怪:1
等待1
通知2
等待2
请找到以下代码:
public class EvenOdd {
public static void main(String[] args) {
PrintEvenOdd p1=new PrintEvenOdd(false);
PrintEvenOdd p2=new PrintEvenOdd(true);
p1.start();
p2.start();
}
}
class PrintEvenOdd extends Thread{
boolean isEven;
boolean isOdd=true;
public PrintEvenOdd(boolean e) {
isEven=e;
}
public synchronized void run() {
if(isEven) {
for(int i=2;i<=10;i+=2)
{
while(isOdd) {
try {
System.out.println("going to wait 1");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Even: "+i);
isOdd=true;
System.out.println("notify 1");
notifyAll();
}
}
if(!isEven) {
for(int i=1;i<=10;i+=2) {
while(!isOdd) {
try {
System.out.println("going to wait 2");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Odd: "+ i);
isOdd=false;
System.out.println("notify 2");
notifyAll();
}
}
}
}
答案 0 :(得分:1)
由于你的算法的主要思想对我来说并不是很明确,我只想指出bug和&amp;你可以尝试自己解决它。
当您一个接一个地启动线程时:p1.start(); p2.start();
它们的执行顺序与我们开始时的顺序相同。
当第一个线程调用同步void run()
方法时,它会将监视器锁定在PrintEvenOdd.class
上。这意味着第二个线程将等到第一个线程释放监视器(假设不会执行任何单行代码)。
通过第一个线程执行流程进一步调试,您将看到以下操作:
if(!isEven)
条件isOdd=false
循环迭代期间设置i=1
wait()
循环迭代i=2
由于wait
操作不会释放类监视器,因此当两个线程都被挂起时你就会遇到这种情况。