[英]print odd and even numbers using two threads in java efficiently?
我在一次采访中被问到下面的问题,我需要使用两个线程打印出偶数和奇数,所以我想出了下面的代码,但在这个我使用两个类,一个实现可运行接口,另一个打印出使用的数字wait
并notifyAll
。
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
类吗?
您可以通过以下方式执行此操作:
不使用同步:
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
。 每个线程打印一个值后,该值会被切换。
使用同步:
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.