0

0

在Java中如何保证多线程下的顺序执行_Java线程控制方式解析

P粉602998670

P粉602998670

发布时间:2026-01-21 17:10:02

|

202人浏览过

|

来源于php中文网

原创

join()是最直接实现线程顺序执行的方式,主线程依次启动t1、t2并调用其join()等待结束;CountDownLatch适用于事件驱动的时序控制,如等待多个线程完成后再启动下一个;synchronized和ReentrantLock仅保证临界区互斥,不控制线程执行顺序;Thread.sleep()因不可靠、不精确而应避免用于顺序控制。

在java中如何保证多线程下的顺序执行_java线程控制方式解析

join() 实现线程顺序执行最直接

如果只是让几个线程按固定顺序一个接一个跑完(比如 t1t2t3),join() 是最轻量、最直观的方式。它会让当前线程阻塞,直到被调用 join() 的线程终止。

  • t1.start() 后立刻调用 t1.join(),主线程就卡在这儿等 t1 结束
  • t2.start() + t2.join(),依此类推
  • 注意:不能在 t1.run() 里调 t2.join() —— 那是在 t1 线程里等 t2,而 t2 可能根本没 start,会永久阻塞
  • 所有 join() 调用必须在启动线程之后、且由同一线程(通常是主线程)发起
Thread t1 = new Thread(() -> System.out.println("t1 done"));
Thread t2 = new Thread(() -> System.out.println("t2 done"));
t1.start();
try { t1.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
t2.start();
try { t2.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }

CountDownLatch 控制多个线程的启动/结束时序

当需要“等前 N 个线程都完成,再启动第 N+1 个”,或者“多个线程都等同一个信号才开始”,CountDownLatchjoin() 更灵活。它的核心是计数器,countDown() 减一,await() 阻塞直到归零。

  • 初始化时传入计数值,比如 new CountDownLatch(2)
  • 前两个线程执行完关键逻辑后各自调一次 latch.countDown()
  • 第三个线程一开始先 latch.await(),只有等够两次 countDown() 才继续
  • join() 不同:它不关心线程对象生命周期,只关心事件发生次数;也支持超时 await(3, TimeUnit.SECONDS) 避免死等
  • 计数器不可重置,用完即弃;需要循环控制请换 CyclicBarrier

synchronizedReentrantLock 保证临界区串行,但不等于线程执行顺序

很多人误以为加锁就能控制线程“谁先谁后运行”,其实不然。synchronizedReentrantLock 只保证同一时刻只有一个线程进入临界区,但哪个线程抢到锁是不确定的——JVM 和 OS 调度决定,不是代码书写顺序。

  • 即使你按 t1t2t3 顺序 start(),也不代表它们按此顺序获得锁
  • 若真要强制顺序(如必须 t1 先改数据、t2 再读),得配合状态变量 + wait()/notify()Condition,复杂度陡增
  • 单纯加锁适合保护共享资源,不适合编排执行流程;强行用锁模拟顺序容易写出活锁或响应延迟高的代码

为什么不用 Thread.sleep() 控制顺序

sleep() “估算”时间来错开线程执行,是典型反模式。它既不精确也不可靠。

Tome
Tome

先进的AI智能PPT制作工具

下载

立即学习Java免费学习笔记(深入)”;

  • CPU 负载高时,sleep(100) 可能实际挂起 200ms 甚至更久
  • 不同机器、JVM 版本、GC 活动都会影响调度精度
  • 无法感知目标线程是否真的完成了工作 —— 它可能刚 sleep 就抛异常退出了
  • 一旦逻辑变复杂(比如某个步骤耗时突增),整个时序就崩,debug 成本远高于用同步原语

真正需要顺序执行的地方,几乎总是存在明确的“完成信号”或“前置依赖”,应该用 join()CountDownLatchCompletableFuture.thenRun() 这类有语义的机制去表达,而不是靠时间硬等。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

32

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

29

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

103

2026.02.06

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

32

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

29

2026.01.21

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.2万人学习

Java 教程
Java 教程

共578课时 | 81.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号