《架构风清扬-Java面试系列第24讲》Java多线程高频笔试题来挑战下!

如何使用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(); // 释放锁
            }
        }
    }
}

这道题虽然简单,在笔试题中出现的频率还是很高的

如果学到更多的干货,欢迎加入我的星球,敢承诺三天内不满意,可以免费退出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值