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资源的争夺,但 ...
随机推荐
- JMeter非GUI模式执行,jtl文件请求与响应数据为空?这里有答案!
JMeter非GUI模式执行,jtl文件请求与响应数据为空?这里有答案! 问题描述 在使用JMeter进行性能测试时,很多用户会选择非GUI(图形用户界面)模式来执行测试,因为这样可以减少客户端的负担 ...
- 文本处理命令head tail more less tr cut paste wc
文本处理命令 命令**head tail more less tr cut paste wc** 磁盘分区利用率 df|tr -s ' ' :|cut -d : -f5 df|tr -s ' ' :| ...
- 最新demo版|如何0-1开发支付宝小程序之前期准备篇(一)
小程序作为目前一种轻量.便捷的应用.目前应用越来越广泛了. 很多没有开发经验的开发同学可能初次接触就是小程序开发,为了详细讲解下小程序开发的步骤,我会按照小程序的开发流程一步一步从零开始给大家介绍下如 ...
- 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
在AI技术飞速发展的今天,大语言模型(LLM)的应用越来越广泛,但高昂的使用成本常常让个人开发者和小型团队望而却步.今天,我要为大家介绍一个非常实用的开源项目--DeepSeek-Free-API,它 ...
- 移动硬盘插入win10检测到却不显示盘符解决方法
1.开始菜单中的设置-----设备. 2.选择"蓝牙和其他设备" 3.在其他设备栏中就能看到检测到的移动硬盘,点击删除设备后重新插入移动硬盘即可在此电脑上显示盘符.
- IDM 下载器 汉化注册激活
将以下程序更改为.bat文件.使用windows的管理员权限打开. 汉化于:https://github.com/WindowsAddict/IDM-Activation-Script @setloc ...
- QT5笔记: 14. SpinBox的常用功能
例子: #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : ...
- ES6语法糖,超甜!
ES6 语法糖 1. ... ... 表示取出可遍历数组中的内容. const arr = new Array() const numbers = [1,2,3,4,5] arr.push(...nu ...
- MediaToolkit:.NET 开发者的多媒体处理工具
MediaToolkit:.NET 开发者的多媒体处理工具 在开发过程中处理音频和视频文件是许多应用程序的重要功能.MediaToolkit 是一个强大的 .NET 库,帮助开轻松处理这些多媒体文件. ...
- P5356 [Ynoi Easy Round 2017] 由乃打扑克
分块典题 左转数列分块入门2 一样的想法 排序+二分 但是发现我们只能求排名 于是二分答案然后分块+二分即可