Java实现三个线程顺序打印

"三个线程按顺序打印"是一个经典的并发编程面试题,通常要求线程 A 打印 1,线程 B 打印 2,线程 C 打印 3,然后循环往复。

实现这个逻辑的核心在于线程间的通信(Signaling) 。我们可以使用 Java 的 synchronized 配合 wait/notify,或者更现代的 ReentrantLock 配合 Condition


方案一:使用 ReentrantLockCondition(推荐)

这是最清晰的方案。我们为每个线程创建一个"信号灯"(Condition),手动控制唤醒哪一个。

java 复制代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SequencePrint {
    private final Lock lock = new ReentrantLock();
    private final Condition cond1 = lock.newCondition();
    private final Condition cond2 = lock.newCondition();
    private final Condition cond3 = lock.newCondition();
    private int state = 1; // 当前应该打印的序号

    public void print(String name, int targetState, Condition current, Condition next) {
        for (int i = 0; i < 10; i++) { // 假设打印10轮
            lock.lock();
            try {
                // 如果还没轮到我,就一直等着
                while (state != targetState) {
                    current.await();
                }
                System.out.print(name + " ");
                // 修改状态并唤醒下一个线程
                state = (targetState % 3) + 1;
                next.signal();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        SequencePrint sp = new SequencePrint();
        new Thread(() -> sp.print("A", 1, sp.cond1, sp.cond2)).start();
        new Thread(() -> sp.print("B", 2, sp.cond2, sp.cond3)).start();
        new Thread(() -> sp.print("C", 3, sp.cond3, sp.cond1)).start();
    }
}

方案二:使用 synchronizedwait/notifyAll(最基础)

这种方式代码最少,但效率略低,因为 notifyAll() 会唤醒所有等待线程,不满足条件的线程会被唤醒后再次检查并挂起。

java 复制代码
public class WaitNotifyPrint {
    private int state = 1;
    private final Object lock = new Object();

    public void print(String name, int targetState) {
        for (int i = 0; i < 10; i++) {
            synchronized (lock) {
                while (state != targetState) {
                    try { lock.wait(); } catch (InterruptedException e) {}
                }
                System.out.print(name);
                state = (state % 3) + 1;
                lock.notifyAll(); // 唤醒所有人,让他们竞争判断 state
            }
        }
    }

    public static void main(String[] args) {
        WaitNotifyPrint wnp = new WaitNotifyPrint();
        new Thread(() -> wnp.print("A", 1)).start();
        new Thread(() -> wnp.print("B", 2)).start();
        new Thread(() -> wnp.print("C", 3)).start();
    }
}

相关推荐
爱码小白几秒前
Python 类五大方法 完整版学习笔记
开发语言·python
XiYang-DING几秒前
【Java EE】定时器
java·python·java-ee
Fuly10245 分钟前
java面试知识点复习
java·开发语言·面试
郭涤生11 分钟前
std::condition_variable的使用及主要事项
开发语言·c++
小菜鸡桃蛋狗16 分钟前
C++——list
开发语言·c++
hopetomorrow25 分钟前
学习路之PHP --PHP 常用扩展及作用表
开发语言·学习·php
信徒_29 分钟前
API 网关技术选型
java
simple-L630 分钟前
Java开发痛点技术文章大纲
java·开发语言
m0_6356474841 分钟前
Qt打包含有第三方库的软件为应用程序——CQtDeployer
开发语言·数据库·qt
simple-L61 小时前
Vue3 前端开发技术文章大纲
开发语言