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资源的争夺,但 ...
随机推荐
- Windows 本地虚拟磁盘
本文介绍如何本地创建虚拟磁盘 虚拟磁盘vhdx是类似物理硬盘一样的磁盘,可以被格式化.内部添加分区,可以指定系统文件格式如NTFS.exFAT 一个vhdx文件对应一个虚拟磁盘,下面我们来操作vhdx ...
- AAAT 笔记(P5649)
实际上去掉主函数不长于线段树 3. 对于 LCT 每个点的虚儿子.用 splay 把它们串起来(称为新 splay,虽然是共用的). 具体来说,设 \(1\le x\le n\) 是原 LCT 的 s ...
- Salt key 系统的接口
官方文档:https://docs.saltstack.com/en/3000/ref/wheel/all/salt.wheel.key.html Wheel 系统包装了Salt key 系统,以编程 ...
- 百万架构师第三十九课:RabbitMq:Linux安装RabbitMq|JavaGuide
来源:https://javaguide.net RPM包安装RabbitMQ RabbitMQ的安装非常简单,由于RabbitMQ依赖于Erlang,所以需要先安装Erlang,解决依赖关系后,就可 ...
- Java - JVM及其调优
原文链接:https://blog.csdn.net/qq_27098537/article/details/124436788 一.什么是JVM 用于运行java代码,包括一套字节码指令集.一组寄存 ...
- Mpmath库-学习笔记
目录 mpmath库学习 1. Introduction 1.2 Basic usage of mpmath 1.3 输出格式化 1.4 输出的小数点位数 2. BASIC FEATURES 2.1 ...
- 【记录】C/C++-关于I/O的坑与教训
吐槽 每每读取字符串时,倘若稍有灵活的操作,总会遇上诡异奇怪的事情.究其原因,就是没完全理解一些基本读写函数的机制.这次做Uva227就把I/O上的问题全暴露出来了.想来还是应该记录一些经验教训. 记 ...
- 市场教父 André Kostolany
大家好,我是 沃伦·爱德华·巴菲特(Warren Edward Buffett,1930 年 8 月 30 日 - ) 查尔斯·托马斯·芒格(Charles Thomas Munger,1924 年 ...
- ModuleNotFoundError: No module named '_ctypes' when Python3
前言 运行 python 报错:ModuleNotFoundError: No module named '_ctypes' when using Value from module multipro ...
- MAMP PRO教程
简单使用 第一步 创建新主机,按主机表左下角的"+"按钮. 第二步 配置域名和项目地址 第三步 选择你要使用的web服务器 第四步 配置URL重写规则 第五步 检查端口号 第六步 ...