如何使用Java多线程,实现奇偶数的交替输出?
来,老规矩,先思考再往下看,效果更佳
PS:图片仅是一个给你缓冲思考的作用
这道题有多种解法,来,三二一,上代码
import java.util.concurrent.atomic.AtomicBoolean;
public class AlternatingNumbers {
private final AtomicBoolean isOddTurn = new AtomicBoolean(true); // 初始时为奇数线程的回合
public static void main(String[] args) {
AlternatingNumbers printer = new AlternatingNumbers();
new Thread(printer::printOdd, "奇数线程").start();
new Thread(printer::printEven, "偶数线程").start();
}
// 奇数线程打印函数
public synchronized void printOdd() {
for (int i = 1; ; i += 2) { // 从1开始打印奇数
while (!isOddTurn.get()) { // 如果不是奇数线程的回合,则等待
try {
this.wait(); // 让出CPU,使当前线程进入等待状态
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 处理中断异常
}
}
System.out.println(Thread.currentThread().getName() + ": " + i); // 打印奇数
isOddTurn.set(false); // 轮到偶数线程
this.notifyAll(); // 唤醒所有等待的线程,让偶数线程有机会执行
}
}
// 偶数线程打印函数
public synchronized void printEven() {
for (int i = 2; ; i += 2) { // 从2开始打印偶数
while (isOddTurn.get()) { // 如果是奇数线程的回合,则等待
try {
this.wait(); // 让出CPU,使当前线程进入等待状态
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 处理中断异常
}
}
System.out.println(Thread.currentThread().getName() + ": " + i); // 打印偶数
isOddTurn.set(true); // 轮到奇数线程
this.notifyAll(); // 唤醒所有等待的线程,让奇数线程有机会执行
}
}
}
当然,还有另一种写法
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class AlternatingNumbers {
private final ReentrantLock lock = new ReentrantLock();
private final Condition oddTurn = lock.newCondition();
private final Condition evenTurn = lock.newCondition();
private boolean isOddTurn = true; // 初始时为奇数线程的回合
public static void main(String[] args) {
AlternatingNumbers printer = new AlternatingNumbers();
new Thread(printer::printOdd, "奇数线程").start();
new Thread(printer::printEven, "偶数线程").start();
}
// 奇数线程打印函数
public void printOdd() {
for (int i = 1; ; i += 2) { // 从1开始打印奇数
lock.lock(); // 获取锁
try {
while (!isOddTurn) { // 如果不是奇数线程的回合,则等待
oddTurn.await(); // 让出CPU,使当前线程进入等待状态
}
System.out.println(Thread.currentThread().getName() + ": " + i); // 打印奇数
isOddTurn = false; // 轮到偶数线程
evenTurn.signalAll(); // 唤醒所有等待的偶数线程
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock(); // 释放锁
}
}
}
// 偶数线程打印函数
public void printEven() {
for (int i = 2; ; i += 2) { // 从2开始打印偶数
lock.lock(); // 获取锁
try {
while (isOddTurn) { // 如果是奇数线程的回合,则等待
evenTurn.await(); // 让出CPU,使当前线程进入等待状态
}
System.out.println(Thread.currentThread().getName() + ": " + i); // 打印偶数
isOddTurn = true; // 轮到奇数线程
oddTurn.signalAll(); // 唤醒所有等待的奇数线程
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock(); // 释放锁
}
}
}
}
这道题虽然简单,在笔试题中出现的频率还是很高的
如果学到更多的干货,欢迎加入我的星球,敢承诺三天内不满意,可以免费退出!