繁体   English   中英

在java中使用两个线程有​​效地打印奇数和偶数?

[英]print odd and even numbers using two threads in java efficiently?

我在一次采访中被问到下面的问题,我需要使用两个线程打印出偶数和奇数,所以我想出了下面的代码,但在这个我使用两个类,一个实现可运行接口,另一个打印出使用的数字waitnotifyAll

public class PrintEvenOddTester {

  public static void main(String[] args) {
    Output print = new Output();
    Thread t1 = new Thread(new EvenOddTask(print, 10, false));
    Thread t2 = new Thread(new EvenOddTask(print, 10, true));
    t1.start();
    t2.start();
  }
}


class EvenOddTask implements Runnable {
  private int max;
  private Output print;
  private boolean isEvenNumber;

  EvenOddTask(Output print, int max, boolean isEvenNumber) {
    this.print = print;
    this.max = max;
    this.isEvenNumber = isEvenNumber;
  }

  @Override
  public void run() {
    int number = isEvenNumber == true ? 2 : 1;
    while (number <= max) {
      if (isEvenNumber) {
        print.printEven(number);
      } else {
        print.printOdd(number);
      }
      number += 2;
    }
  }
}


class Output {
  boolean isOdd = false;

  public synchronized void printEven(int number) {
    while (isOdd == false) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.println("Even:" + number);
    isOdd = false;
    notifyAll();
  }

  public synchronized void printOdd(int number) {
    while (isOdd == true) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.println("Odd:" + number);
    isOdd = true;
    notifyAll();
  }
}

我想检查在 Java 7 中是否有更好或更简单的方法来完成这些任务。一般来说,我可以不直接在EvenOddTask类中打印出来而不是使用另一个Output类吗?

您可以通过以下方式执行此操作:

  1. 不使用同步:

     class Print { private static int count = 1; private static int MAX = 20; private boolean isOdd = true; public void printEven() { while (true) { if (count > MAX) break; if (!isOdd) { System.err.println(Thread.currentThread().getName() + ":" + count++); isOdd = true; } } } public void printOdd() { while (true) { if (count > MAX) break; if (isOdd) { System.err.println(Thread.currentThread().getName() + ":" + count++); isOdd = false; } } } } public class ThreadOddEven { public static void main(String[] args) { Print p = new Print(); // Thread t1 = new Thread(() -> p.printEven()); Thread t1 = new Thread(new Runnable() { @Override public void run() { p.printEven(); } }); t1.setName("EVEN"); // Thread t2 = new Thread(() -> p.printOdd()); Thread t2 = new Thread(new Runnable() { @Override public void run() { p.printOdd(); } }); t2.setName("ODD"); t1.start(); t2.start(); } }

    这可能是实现跨两个线程打印奇数和偶数的最简单方法。

    这里我们只是使用了一个布尔变量isOdd 每个线程打印一个值后,该值会被切换。

  2. 使用同步:

     class Print2 { private static int count = 1; private static int MAX = 10; private Object obj = new Object(); public void printEven() { while (true) { if (count > MAX) break; synchronized (obj) { System.err.println(Thread.currentThread().getName() + " : " + count++); obj.notify(); try { obj.wait(); } catch (InterruptedException e) { } } } } public void printOdd() { while (true) { if (count > MAX) break; synchronized (obj) { System.err.println(Thread.currentThread().getName() + " : " + count++); obj.notify(); try { obj.wait(); } catch (InterruptedException e) { } } } } }

    在第二个例子中,我们没有使用布尔变量,而是使用一个对象,以便我们可以同步两个线程之间的调用。

    这个类的主要方法调用与上面的例子相同。

暂无
暂无

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

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