Java线程控制: sleep、yield、join深度解析
结论先行
- sleep:主动让出CPU但保持锁,适合控制执行节奏和优化CPU占用
- yield:建议让出CPU但无强制力,适用场景有限且效果不稳定
- join:通过等待机制实现线程顺序控制,底层基于wait实现锁释放
- 锁机制:sleep/yield不释放锁,join通过wait释放目标线程锁
- 性能优化:sleep(0)是实际开发中的高频优化技巧
文章持续更新,可以微信搜一搜「 半个脑袋儿 」第一时间阅读
一、sleep方法
核心特性
public static native void sleep(long millis) throws InterruptedException;
- 锁机制:保持当前线程持有的所有锁(不释放synchronized锁)
- CPU状态:从运行状态进入超时等待(TIMED_WAITING)
- 中断响应:可通过interrupt()中断等待
经典场景
- GC优化:在快速循环中插入sleep(0)
while (true) {
processBatch();
Thread.sleep(0); // 让出CPU给GC线程
}
- 降低CPU占用:批处理任务降频
for (int i = 0; i < 1_000_000; i++) {
processItem();
if (i % 100 == 0) {
Thread.sleep(1); // 每100次休眠1ms
}
}
实现原理
通过native方法实现操作系统级别的定时器调度,不同系统实现差异:
- Linux:基于nanosleep系统调用
- Windows:使用WaitForSingleObject
二、yield方法
核心特性
public static native void yield();
- 锁机制:保持当前线程持有的所有锁
- CPU状态:从运行状态回到就绪状态(RUNNABLE)
- 调度策略:依赖具体JVM实现(多数情况无效果)
适用场景
// 多线程并行执行相同任务
class ParallelTask implements Runnable {
public void run() {
while (!done) {
computeStep();
Thread.yield(); // 建议让出CPU
}
}
}
实现局限
- HotSpot VM中实际效果等同于短暂休眠(约1ms)
- 无法保证公平性,可能被调度器完全忽略
- 不同JVM实现差异大(如Zing VM有优化)
三、join方法
核心特性
public final synchronized void join() throws InterruptedException {
// 基于wait实现
while (isAlive()) {
wait(0);
}
}
- 锁机制:释放目标线程的监视器锁(通过wait)
- 等待方式:循环检测线程存活状态
- 中断处理:支持InterruptedException
典型用法
Thread worker = new Thread(task);
worker.start();
// 主线程等待worker完成
try {
worker.join();
} catch (InterruptedException e) {
handleInterruption();
}
// 继续执行后续逻辑
processResult();
方法对比表
| 特性 | sleep | yield | join |
|---|---|---|---|
| 锁释放 | 不释放 | 不释放 | 释放目标线程锁 |
| CPU状态 | TIMED_WAITING | RUNNABLE | WAITING |
| 中断响应 | 支持 | 不支持 | 支持 |
| 参数控制 | 精确时间控制 | 无 | 可设超时时间 |
| 使用频率 | 高频 | 极少 | 中频 |
最佳实践建议
- 避免滥用sleep:长时休眠应使用LockSupport.parkNanos()
- 替代yield方案:优先考虑wait/notify或Condition
- join超时保护:始终使用带超时的join方法
worker.join(5000); // 最多等待5秒
- 线程池整合:使用Future.get()替代join实现任务编排
- 响应中断:正确处理InterruptedException
通过合理组合使用这三个方法,可以实现精细化的线程控制,但需牢记:现代多线程开发更推荐使用java.util.concurrent包的高级API。
Java线程控制: sleep、yield、join深度解析的更多相关文章
- java多线程之yield,join,wait,sleep的区别
Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...
- Java线程sleep,yield,join,wait方法详解
1.sleep() 当一个线程调用sleep方法后,他就会放弃cpu,转到阻塞队列,sleep(long millis)方法是Thread类中的静态方法,millis参数设定线程睡眠的时间,毫秒为单位 ...
- Java 线程控制
一.线程控制 和线程相关的操作都定义在Thread类中,但在运行时可以获得线程执行环境的信息.比如查看可用的处理器数目(这也行?): public class RunTimeTest { public ...
- Java中sleep,wait,yield,join的区别
sleep() wait() yield() join()用法与区别 1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”.不推荐使用. sleep()使当前线程 ...
- Java多线程1:Java中sleep,wait,yield,join的区别
1.sleep()方法 在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”.不推荐使用. sleep()使当前线程进入阻塞状态,在指定时间内不会执行. 2.wait()方法 在其他线程调用 ...
- 并发编程——线程中sleep(),yield(),join(),wait(),notify(),notifyAll()区别
前言 今天简单的讲一讲线程中sleep(),join(),yield(),wait(),notify(),notifyAll()这些方法的使用以及区别. 不过在讲这些方法之前,需要简单的介绍一下锁池和 ...
- java线程控制、状态同步、volatile、Thread.interupt以及ConcurrentLinkedQueue
在有些严格的系统中,我们需要做到干净的停止线程并清理相关状态.涉及到这个主题会带出很多的相关点,简单的总结如下: 我们知道,在java中,有一个volatile关键字,其官方说明(https://do ...
- Java 线程池架构原理和源码解析(ThreadPoolExecutor)
在前面介绍JUC的文章中,提到了关于线程池Execotors的创建介绍,在文章:<java之JUC系列-外部Tools>中第一部分有详细的说明,请参阅: 文章中其实说明了外部的使用方式,但 ...
- java线程控制安全
synchronized() 在线程运行的时候,有时会出现线程安全问题例如:买票程序,有可能会出现不同窗口买同一张编号的票 运行如下代码: public class runable implement ...
- java线程学习之yield方法
yield方法是暂停当前正在执行的线程对象,并执行其他线程. 这是一个静态方法,一旦执行,它会使当前线程让出CPU.让出的cpu并不代表当前线程不执行了.当前线程让出CPU后,还会CPU资源的争夺,但 ...
随机推荐
- SuiteCRM 7.11.18 安装及汉化
SuiteCRM 7.11.18 安装及汉化 sourceforge下载,github也有https://sourceforge.net/projects/suitecrm/files/SuiteCR ...
- linux更新软件源 安装docker
vim /etc/aptsources.list 学习参考 https://blog.csdn.net/bskfnvjtlyzmv867/article/details/81044217 # 默认 ...
- 埋点-App层丢失率
一.建表语句 create table dws_bhv_habo_measure_lostrate_mb_di( version_flag bigint comment '版本标签 2:web丢失 3 ...
- [THUSC2015] 异或运算 题解
学到新思路了:求解 \(k\) 大值时,可以将所有元素放一块一起跑. 考虑到 \(n,q\) 奇小无匹,我们便可以制造一个 \(O(qn\log V)\) 的代码. 那么对于我们不想在时间复杂度中出现 ...
- css的度量单位:px、em、rem、vh、vw、vmin、vmax、百分比
css的度量单位 px,像素数量,适用于比较固定的场景,比如边框宽度,分割线宽度 em em:是描述相对于应用在当前元素的字体尺寸,所以它也是相对长度单位.一般浏览器字体大小默认为16px,则2em ...
- MySQL - [06] 测试数据
题记部分 一.死神测试数据 嗷嗷待"补" 二.火影忍者测试数据 -- 忍村表 create table hy_villages( VillageID INT PRIMARY KEY ...
- Linux - lvm逻辑卷的操作
执行 lsblk如下所示: [root@idc-poc-60 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 3.7G 0 r ...
- Markdown 编写技巧汇总(二)
继续上篇汇总 附-上篇汇总,接着做更加高级一点的应用技巧. [1]列表与引言嵌套 两者嵌套,如: > 我是一行文本 > 1. 文本1 > 2. 文本2 > 1. 文本 > ...
- 【BUUCTF】Easy MD5
[BUUCTF]Easy MD5 (SQL注入.PHP代码审计) 题目来源 收录于:BUUCTF BJDCTF2020 题目描述 抓包得到提示 select * from 'admin' where ...
- Supac 如何修改地址界限高层点
编辑->图层->运算 2.选择z ->填写高度 如-180阶段 3.保存