在 java 中使用两个线程有效地打印奇数和偶数?
print odd and even numbers using two threads in java efficiently?
我在一次采访中被问到下面的问题,我需要使用两个线程打印出偶数和奇数,所以我想出了下面的代码,但在这里我使用了两个 classes 一个实现 runnable接口和其他打印出使用 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 中是否有更好或更简单的方法来完成这些任务。一般来说,而不是使用另一个 Output
class,我可以在EvenOddTask
class?
中直接打印不出来
您可以通过以下方式进行:
不使用同步:
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) { }
}
}
}
}
在第二个例子中,我们没有使用布尔变量,而是
使用一个对象,以便我们可以同步两者之间的调用
线程。
这个class的main方法调用和上面的例子一样
我在一次采访中被问到下面的问题,我需要使用两个线程打印出偶数和奇数,所以我想出了下面的代码,但在这里我使用了两个 classes 一个实现 runnable接口和其他打印出使用 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 中是否有更好或更简单的方法来完成这些任务。一般来说,而不是使用另一个 Output
class,我可以在EvenOddTask
class?
您可以通过以下方式进行:
不使用同步:
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) { } } } } }
在第二个例子中,我们没有使用布尔变量,而是 使用一个对象,以便我们可以同步两者之间的调用 线程。
这个class的main方法调用和上面的例子一样