两个线程交替打印0~100的奇偶数?
参考答案:
这个问题是一个常见的多线程同步问题,可以使用Java中的wait和notify方法,或者更现代的Semaphore,CyclicBarrier,CountDownLatch,Lock和Condition等同步工具来解决。这里我会给出使用wait和notify的示例,以及使用Semaphore的示例。
使用wait和notify的示例
public class OddEvenPrinter {
private int number = 1;
private final int MAX_NUMBER = 100;
private final Object oddLock = new Object();
private final Object evenLock = new Object();
public void printOdd() {
while (number <= MAX_NUMBER) {
synchronized (oddLock) {
while (number % 2 == 0) {
try {
oddLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ": " + number);
number++;
evenLock.notify();
}
}
}
public void printEven() {
while (number <= MAX_NUMBER) {
synchronized (evenLock) {
while (number % 2 != 0) {
try {
evenLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ": " + number);
number++;
oddLock.notify();
}
}
}
public static void main(String[] args) {
OddEvenPrinter printer = new OddEvenPrinter();
Thread oddThread = new Thread(() -> printer.printOdd(), "OddThread");
Thread evenThread = new Thread(() -> printer.printEven(), "EvenThread");
oddThread.start();
evenThread.start();
}
}
在这个示例中,我们创建了两个锁对象oddLock和evenLock,分别用于控制奇数和偶数的打印。printOdd方法只打印奇数,而printEven方法只打印偶数。当number为奇数时,printOdd方法会打印它并通知printEven方法可以继续执行;当number为偶数时,情况相反。我们使用wait方法让线程等待,直到条件满足(即number变为期望的奇偶性),然后使用notify方法唤醒等待的线程。
使用Semaphore的示例
import java.util.concurrent.Semaphore;
public class OddEvenPrinterWithSemaphore {
private int number = 1;
private final int MAX_NUMBER = 100;
private final Semaphore oddSemaphore = new Semaphore(1);
private final Semaphore evenSemaphore = new Semaphore(0);
public void printOdd() throws InterruptedException {
for (; number <= MAX_NUMBER; number += 2) {
oddSemaphore.acquire();
System.out.println(Thread.currentThread().getName() + ": " + number);
evenSemaphore.release();
}
}
public void printEven() throws InterruptedException {
for (int i = 2; i <= MAX_NUMBER; i += 2) {
evenSemaphore.acquire();
System.out.println(Thread.currentThread().getName() + ": " + i);
oddSemaphore.release();
}
}
public static void main(String[] args) {
OddEvenPrinterWithSemaphore printer = new OddEvenPrinterWithSemaphore();
Thread oddThread = new Thread(() -> {
try {
printer.printOdd();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "OddThread");
Thread evenThread = new Thread(() -> {
try {
printer.printEven();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "EvenThread");
oddThread.start();
evenThread.start();
}
}
在这个示例中,我们使用两个Semaphore来控制奇数和偶数的打印。oddSemaphore初始时有一个许可,允许打印第一个奇数;evenSemaphore初始时没有许可,因此打印偶数的线程会立即阻塞。当打印奇数的线程打印完一个奇数并释放evenSemaphore的一个许可