当前位置: 首页 > news >正文

从一道面试题开始:如何让同时启动的线程按顺序执行?

最近准备面试刷题,遇到一个多线程问题:如何让 A、B、C 三个线程同时启动,却要按顺序先后执行(A -> B -> C)。

直觉上,“同时启动”意味着线程调度权交给操作系统,执行顺序理应不确定。那如何控制顺序?若让后一个线程等待前一个执行完毕,似乎又违背了“同时启动”的要求。

最初尝试 Thread.join():让 B 等待 A 执行完,C 等待 B 执行完,再按顺序启动它们。但很快发现问题——如果 B 和 C 的初始化逻辑依赖 A 对象,它们甚至无法在 A 启动前被创建。这本质上只是“顺序启动”,而非题目要求的“同时启动但顺序执行”。

理解关键点:

  • start() 仅通知系统线程就绪,run() 方法内的逻辑何时执行取决于 CPU 调度。
  • “启动”是状态,“执行”是动作,“等待”是一种阻塞状态。
  • 核心在于控制 run() 方法中关键逻辑的执行顺序,而非启动顺序本身。

使用 CountDownLatch 实现: CountDownLatch 是一个类似发令枪的同步工具。其核心是一个计数器:初始化设定计数值,线程调用 await() 阻塞等待;其他线程完成任务后调用 countDown() 减 1;当计数器归零,所有等待线程被唤醒继续执行。

利用两个 CountDownLatch:一个控制 B 等待 A 完成,一个控制 C 等待 B 完成。

public class ThreadOrder {public static void main(String[] args) {// 控制B等待A的信号CountDownLatch latchBwaitsA = new CountDownLatch(1);// 控制C等待B的信号CountDownLatch latchCwaitsB = new CountDownLatch(1);Thread a = new Thread(() -> {System.out.println("A starts");latchBwaitsA.countDown(); // A执行完毕,释放B线程的阻塞});Thread b = new Thread(() -> {try {latchBwaitsA.await(); // B等待A完成信号System.out.println("B starts");latchCwaitsB.countDown(); // B执行完毕,释放C线程的阻塞} catch (InterruptedException e) {Thread.currentThread().interrupt();}});Thread c = new Thread(() -> {try {latchCwaitsB.await(); // C等待B完成信号System.out.println("C starts");} catch (InterruptedException e) {Thread.currentThread().interrupt();}});// 真正的“同时启动”a.start();b.start();c.start();}
}

输出结果:

A starts
B starts
C starts

最关键的是,三个线程的 start() 方法几乎在同一时刻被调用,满足了“同时启动”的要求;而 run() 方法中关键逻辑的执行顺序(打印语句)则通过 CountDownLatch 实现了严格的 A -> B -> C 顺序,没有破坏“同时启动”的前提。

http://www.dtcms.com/a/365276.html

相关文章:

  • 物联网能源管控平台建设方案
  • PostgreSQL 技术峰会哈尔滨站活动回顾|深度参与 IvorySQL 开源社区建设的实践与思考
  • FPGA ad9248驱动
  • 计算机视觉(六):腐蚀操作
  • 生产环境中redis的SCAN命令如何替代KEYS命令?
  • 苍穹外卖项目笔记day04--Redis入门
  • ITU-R P.372 无线电噪声预测库调用方法
  • 存算一体:重构AI计算的革命性技术(1)
  • 【LeetCode_283】移动零
  • 配置机载电脑开机自启动ros2节点和配置can0
  • 抗体的应用
  • Mysql学习第五天 Innodb底层原理与Mysql日志机制深入剖析
  • 视频数据如何联网共享?
  • 【底层机制】【C++】vector 为什么等到满了才扩容而不是提前扩容?
  • 编程基础-java开发准备
  • 采用基于模型的方法实现车辆SOA威胁分析自动化
  • 华为云云原生架构赋能:大腾智能加速业务创新步伐
  • HTML第八课:HTML4和HTML5的区别
  • 从零开始学大模型之Transformer 架构
  • 鹧鸪云软件:光伏施工管理一目了然,进度尽在掌握
  • 【Python语法基础学习笔记】类的定义和使用
  • 面试复习题-Flutter场景题
  • C# 开发 ACS 运动控制系统:从入门到高阶应用实践
  • LSE录取率上升,中国申请者却减少!除了成绩,这点成关键胜负手
  • 跟做springboot尚品甄选项目
  • 逻辑回归:从原理到实战的完整指南
  • Spring AOP注解案例
  • AI 重塑就业市场:哪些职业会被替代?又有哪些新岗位正在崛起?
  • 基于https+域名的Frp内网穿透教程(Linux+Nginx反向代理)
  • python数据分析 与spark、hive数据分析对比