两个线程交替打印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
的一个许可