我使用2个线程打印甚至奇数到10的错误是什么问题

时间:2017-10-11 18:25:00

标签: java multithreading

我试图使用两个不同的线程打印偶数和奇数。有人可以指出我犯的错误。 目前这是输出的样子:

奇怪: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();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

由于你的算法的主要思想对我来说并不是很明确,我只想指出bug和&amp;你可以尝试自己解决它。

当您一个接一个地启动线程时:p1.start(); p2.start();它们的执行顺序与我们开始时的顺序相同。

当第一个线程调用同步void run()方法时,它会将监视器锁定在PrintEvenOdd.class上。这意味着第二个线程将等到第一个线程释放监视器(假设不会执行任何单行代码)。

通过第一个线程执行流程进一步调试,您将看到以下操作:

  • 下拉到if(!isEven)条件
  • isOdd=false循环迭代期间设置i=1
  • wait()循环迭代
  • 期间转到无尽的i=2

由于wait操作不会释放类监视器,因此当两个线程都被挂起时你就会遇到这种情况。