简体   繁体   English

奇数偶数序列Java 2线程

[英]Odd even sequence java 2 thread

I am trying to write a program with two Java threads. 我正在尝试用两个Java线程编写程序。 One shall print odd and the other shall print even numbers. 一个应打印奇数,另一个应打印偶数。 The output should be in sequence. 输出应按顺序。 My code is not working properly. 我的代码无法正常工作。 Please correct it and tell me what was the error. 请更正并告诉我错误是什么。

public class App {

  public static void main(String[] args) {
    ThrdO to=new ThrdO();
    Thread t1=new Thread(to);

    ThredE te=new ThredE();
    Thread t2=new Thread(te);
    t1.start();


    t2.start();
 }

}

public class ThrdO implements Runnable{

  PrintCl pcl =new PrintCl();

  @Override
  public void run() {
    for(int i=0;i<10;i+=2)
    pcl.Even(i);    
  }
}


public class ThredE implements Runnable {

    PrintCl pcl =new PrintCl();

    @Override
    public void run() {
      for(int i=1;i<10;i+=2)
        try {
          pcl.odd(i);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }   
     }

public class PrintCl {
    public void Even(int n) {
      synchronized (this) {
        System.out.println(n);
        this.notifyAll();
        try {
            this.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      }         
    }

    public void odd(int n) throws InterruptedException {

        synchronized (this) {
          System.out.println(n);
          this.notifyAll();
          this.wait();  
        }
    }
}

getting output 得到输出

0 ,1 0,1

This is a much cleaner way of achieving what you want, without ugly sleeps in the code, not to mention that it will run faster than code with a sleep in it, for obvious reasons. 这是一种实现所需目标的更干净的方法,无需在代码中进行繁琐的睡眠,更不用说由于明显的原因,它的运行速度将比带有睡眠的代码运行得更快。

public class App {

    public static void main(String[] args) {
        PrintCl pcl = new PrintCl();

        Thread t1 = new Thread(new ThrdEven(pcl));
        Thread t2 = new Thread(new ThrdOdd(pcl));

        t1.start();
        t2.start();
    }
}

public class ThrdEven implements Runnable {

    private PrintCl pcl = null;

    public ThrdEven(PrintCl pcl) {
        this.pcl = pcl;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i += 2) {
            pcl.Even(i);
        }
    }
}

public class ThrdOdd implements Runnable {

    private PrintCl pcl = null;

    public ThrdOdd(PrintCl pcl) {
        this.pcl = pcl;
    }

    @Override
    public void run() {
        for (int i = 1; i < 10; i += 2) {
            pcl.odd(i);
        }
    }
}

public class PrintCl {

    private final Object _lock = new Object();
    private boolean isEvenAllowed = true;

    public void Even(int n) {
        synchronized (this._lock) {
            while (!this.isEvenAllowed) {
                try {
                    this._lock.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);
                }
            }
            System.out.println(n);
            this.isEvenAllowed = false;
            this._lock.notifyAll();
        }
    }

    public void odd(int n) {
        synchronized (this._lock) {
            while (this.isEvenAllowed) {
                try {
                    this._lock.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);
                }
            }
            System.out.println(n);
            this.isEvenAllowed = true;
            this._lock.notifyAll();
        }
    }
}

Please try following changes in your code: 请尝试对代码进行以下更改:

public class App {

  public static void main(String[] args) throws InterruptedException {

  PrintCl pcl =new PrintCl();

  ThrdO to=new ThrdO();
  to.setPcl(pcl);
  Thread t1=new Thread(to);

  ThredE te=new ThredE();
  te.setPcl(pcl);
  Thread t2=new Thread(te);
  t1.start();
  Thread.sleep(1000);
  t2.start();

 }
}

And for Thrd0: 对于Thrd0:

public class ThrdO implements Runnable  {

  PrintCl pcl =null;

  @Override
  public void run() {
    for(int i=0;i<10;i+=2)
    pcl.Even(i);

  }

  public PrintCl getPcl() {
    return pcl;
  }

  public void setPcl(PrintCl pcl) {
    this.pcl = pcl;
  }


}

ThredE: ThredE:

public class ThredE implements Runnable {

  PrintCl pcl =null;

  @Override
  public void run() {
    for(int i=1;i<10;i+=2)
        try {
            pcl.odd(i);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

  }

  public PrintCl getPcl() {
    return pcl;
  }

  public void setPcl(PrintCl pcl) {
    this.pcl = pcl;
  }
}

Your code has two basic problems 您的代码有两个基本问题

  1. Every thread have its own printing resource . 每个线程都有其自己的printing resource Hence once printing their first number they are waiting for notification endlessly. 因此,一旦打印了他们的第一个号码,他们将无休止地等待通知。
  2. Once you will fix this issue , Another issue is your one thread will be finished but second thread would still be waiting for its notification and it will never die. 解决此问题后,另一个问题是您的一个线程将完成,但是第二个线程仍在等待其通知,并且永远不会死。

I have fixed both issues in below code 我已修复以下代码中的两个问题

 public class Test {
    public static void main(String[] args) throws InterruptedException {

        PrintCl pcl =new PrintCl();
        ThrdO to=new ThrdO(pcl);
        Thread t1=new Thread(to);

        ThredE te=new ThredE(pcl);
        Thread t2=new Thread(te);
        t1.start();
        Thread.sleep(1000);// just to ensure that T1 should start first
        t2.start();
    }


}
class ThrdO implements Runnable{


    private PrintCl pcl;

    public ThrdO(PrintCl pcl) {
        this.pcl = pcl;
    }

    @Override
    public void run() {
        for(int i=0;i<10;i+=2) {
            try {
                pcl.Even(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (pcl){
            System.out.println("Releasing lock on pcl");
            pcl.notify();
        }
        System.out.println("ThrdO has finished its working");
    }
}

class ThredE implements Runnable {

    PrintCl pcl ;

    public ThredE(PrintCl pcl) {

        this.pcl = pcl;
    }

    @Override
    public void run() {
        for (int i = 1; i < 10; i += 2) {
            try {
                pcl.odd(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (pcl){
            System.out.println("Releasing lock on pcl ");
            pcl.notify();
        }
        System.out.println("ThredE has finished its working");

    }
}

    class PrintCl {
        public void Even(int n) throws InterruptedException {
            synchronized (this) {
                System.out.println("even - "+n);
                this.notifyAll();
                    this.wait();
            }
        }

        public void odd(int n) throws InterruptedException {

            synchronized (this) {
                System.out.println("odd "+n);
                this.notifyAll();
                this.wait();
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM