You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用不同线程按指定顺序打印三句的Java代码实现示例

让多线程按指定顺序打印句子的Java实现方案

嘿,这个问题我太熟悉了!要让不同的线程分别打印三句话,还得严格按顺序输出,核心就是给线程加上同步控制,确保它们按预定的顺序执行。我给你分享三种实战中常用的实现方法,每种都附代码和简单解释~

方法一:用Thread.join()实现(最简单直观)

join()方法的作用是让当前线程等待调用join()的线程执行完毕后再继续运行。我们可以利用这个特性,让主线程依次控制三个线程的启动顺序:

public class OrderedPrinting {
    public static void main(String[] args) throws InterruptedException {
        // 创建三个分别打印对应句子的线程
        Thread t1 = new Thread(() -> System.out.println("Hello there."));
        Thread t2 = new Thread(() -> System.out.println("How are you?"));
        Thread t3 = new Thread(() -> System.out.println("Thank you, very much!"));

        // 先启动t1,等它打印完再启动t2,以此类推
        t1.start();
        t1.join(); // 主线程暂停,直到t1执行结束
        t2.start();
        t2.join(); // 主线程暂停,直到t2执行结束
        t3.start();
    }
}

这种方法的优点是代码简洁、容易理解,适合场景简单的顺序执行需求。缺点是线程是串行启动的,没有真正的并发启动,但对于这个问题来说完全够用。

方法二:用CountDownLatch实现(支持并发启动线程)

如果想让所有线程提前启动,但仍按顺序执行,可以用CountDownLatch这个同步工具类。它允许线程等待其他线程完成操作后再继续:

import java.util.concurrent.CountDownLatch;

public class OrderedPrintingWithLatch {
    public static void main(String[] args) {
        // 创建两个闩锁,分别用于t2等待t1、t3等待t2
        CountDownLatch latchForT2 = new CountDownLatch(1);
        CountDownLatch latchForT3 = new CountDownLatch(1);

        Thread t1 = new Thread(() -> {
            System.out.println("Hello there.");
            latchForT2.countDown(); // t1完成,通知t2可以开始
        });

        Thread t2 = new Thread(() -> {
            try {
                latchForT2.await(); // 等待t1的完成信号
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 处理中断,良好的并发实践
            }
            System.out.println("How are you?");
            latchForT3.countDown(); // t2完成,通知t3可以开始
        });

        Thread t3 = new Thread(() -> {
            try {
                latchForT3.await(); // 等待t2的完成信号
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Thank you, very much!");
        });

        // 这里可以任意顺序启动线程,它们会自己等待依赖信号
        t3.start();
        t2.start();
        t1.start();
    }
}

这种方法的好处是线程可以并发启动,但内部通过闩锁控制执行顺序,适合更复杂的并发场景,扩展性也更好。

方法三:用wait()/notify()实现(理解线程通信核心)

如果想深入理解Java线程间的通信机制,可以用对象的内置锁配合wait()和notify()方法,通过共享状态来控制轮次:

public class OrderedPrintingWithWaitNotify {
    // 共享状态:标记当前该哪个线程执行(1=t1,2=t2,3=t3)
    private static int currentTurn = 1;
    // 共享锁对象,所有线程共用同一个监视器
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> printMessage("Hello there.", 1));
        Thread t2 = new Thread(() -> printMessage("How are you?", 2));
        Thread t3 = new Thread(() -> printMessage("Thank you, very much!", 3));

        t1.start();
        t2.start();
        t3.start();
    }

    private static void printMessage(String message, int turn) {
        synchronized (lock) {
            try {
                // 如果不是当前线程的轮次,就进入等待状态
                while (currentTurn != turn) {
                    lock.wait();
                }
                // 轮到自己了,打印消息
                System.out.println(message);
                // 更新轮次,通知所有等待的线程
                currentTurn++;
                lock.notifyAll();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

这种方法是Java并发编程的基础,能帮你理解对象监视器、等待/通知机制的核心原理,适合想深入学习并发的同学。

内容的提问来源于stack exchange,提问作者Hussain Ashruf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:33:10