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();
    }
}

相关推荐
项目題供诗13 小时前
C语言基础(十)
c语言·开发语言
代码游侠13 小时前
学习笔记——GPIO按键与中断系统
c语言·开发语言·arm开发·笔记·嵌入式硬件·学习·重构
R-sz13 小时前
app登录接口实现,基于JWT的APP登录认证系统实现方案
java·开发语言·python
无籽西瓜a13 小时前
ArrayList和LinkedList的区别
java
Elieal13 小时前
@Api 系列注解
java·开发语言
Remember_99313 小时前
【数据结构】深入理解Map和Set:从搜索树到哈希表的完整解析
java·开发语言·数据结构·算法·leetcode·哈希算法·散列表
小楼v13 小时前
消息队列的核心概念与应用(RabbitMQ快速入门)
java·后端·消息队列·rabbitmq·死信队列·交换机·安装步骤
浅念-13 小时前
C++第一课
开发语言·c++·经验分享·笔记·学习·算法
Coding茶水间13 小时前
基于深度学习的路面裂缝检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
开发语言·人工智能·深度学习·yolo·目标检测·机器学习