yield和sleep的区别

本文详细解析了Java线程API文档中的yield和sleep方法,对比了它们在线程生命周期中的不同作用,特别是如何影响线程的运行状态以及与CPU时间竞争的关系。同时指出这两种方法在执行前后都不具备同步语义,强调了它们在多线程环境下的使用注意事项。

JDK1.5.0的API文档里的描述:

yield:Causes the currently executing thread object to temporarily pause and allow other threads to execute.

sleep:Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds.

根本无助于理解两者间的差别

 

线程的生命周期里有三个状态Runable、Blocked、Running

yield:Running  ->  Runable

sleep: Running -> Blocked -> Runable

yield和sleep都是在线程处于Running的时候开始的,yield只是让出分配给自己的CPU时间片,并且会立刻进入Runable状态参与CPU时间的竞争,若程序中没有其他线程,那么该线程马上就会开始往下执行;sleep会进入Blocked状态,等待时间结束事件的发生,然后进入Runable状态参与CPU时间的竞争

 

另外,sleep和yield都不具备同步语义,也就是说编译器在执行sleep或yield方法之前和之后,都没有强制要求同步本地缓存与主存的数据

以下摘自JSL3.0

 

 

It is important to note that neither Thread.sleep nor Thread.yield have

any synchronization semantics. In particular, the compiler does not have to flush

writes cached in registers out to shared memory before a call to Thread.sleep or

Thread.yield, nor does the compiler have to reload values cached in registers

after a call to Thread.sleep or Thread.yield.

 

 

For example, in the following (broken) code fragment, assume that this.done is a non-volatile

boolean field:

 

The compiler is free to read the field this.done just once, and reuse the cached value

in each execution of the loop. This would mean that the loop would never terminate, even if

another thread changed the value of this.done.

 

 

 

### sleepyield区别与联系 在 Java 多线程编程中,`sleep` `yield` 是 `Thread` 类提供的两个用于控制线程执行的方法。它们在行为、状态转换、资源控制以及应用场景上存在显著差异。 #### 线程状态变化 - `sleep` 方法会使当前线程从运行状态(Running)进入阻塞状态(Blocked),在指定的时间内不会参与 CPU 的调度。时间结束后,线程会自动回到就绪状态(Runnable),等待调度器重新分配 CPU 时间[^3]。 - `yield` 方法则不会使线程进入阻塞状态,而是让出当前的 CPU 时间片,使线程重新回到就绪状态。线程会立即参与 CPU 时间的竞争,如果此时没有其他同优先级或更高优先级的线程等待,则该线程可能立刻被重新调度执行[^1]。 #### 优先级考虑 - `sleep` 方法不考虑线程优先级,所有线程都有机会获得 CPU 时间[^4]。 - `yield` 方法则会优先考虑同优先级或更高优先级的线程。 #### 是否释放锁资源 - 两者都不会释放线程持有的对象锁资源。这意味着在同步代码块或同步方法中调用 `sleep` 或 `yield`,线程仍然持有锁,其他线程无法进入该同步代码块[^2]。 #### 方法参数与异常 - `sleep` 方法具有参数,用于指定线程休眠的时间长度,在 `Thread` 类中有两种重载形式:`sleep(long millis)` `sleep(long millis, int nanos)`。该方法声明抛出 `InterruptedException`,因此在调用时需要处理或声明该异常[^4]。 - `yield` 方法没有参数,也不抛出任何异常,其行为由 JVM 实现决定。 #### 可移植性与适用性 - `sleep` 方法的行为在不同平台下较为一致,具有较好的可移植性。 - `yield` 方法的行为则可能因 JVM 实现操作系统调度策略的不同而有所差异,因此在跨平台应用中使用时需谨慎[^4]。 #### 应用场景 - `sleep` 常用于需要定时休眠的场景,例如定时任务、限流控制、模拟延迟等[^3]。 - `yield` 更适合用于线程调度优化,特别是在多个线程竞争 CPU 时间时,用于主动让出 CPU 以提升整体调度效率,尤其是在同优先级线程之间[^1]。 #### 示例代码 以下是一个简单的示例,展示 `sleep` `yield` 的使用方式: ```java public class SleepVsYield { public static void main(String[] args) { Thread sleepThread = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println("Sleeping Thread: " + i); try { Thread.sleep(1000); // 线程休眠1秒 } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread yieldThread = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println("Yielding Thread: " + i); Thread.yield(); // 让出CPU } }); sleepThread.start(); yieldThread.start(); } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值