Java Thread.sleep(0)的存在有意义吗?

本文探讨了Thread.sleep(0)方法的实际作用及其在操作系统调度中的意义。通过介绍Unix的时间片算法与Windows的抢占式算法,解释了此方法如何帮助进程主动放弃CPU使用权,促进资源的合理分配。

问题

Thread.sleep(millisecond)方法通常用来使线程挂起一段时间。

但是使用sleep(0)似乎和不使用没什么区别,那他的存在没有意义吗?

思考

这其实和操作系统原理有关。

在操作系统中,一般有很多程序来争夺CPU的使用权,而这个争夺有很多策略。

Unix系统使用的是时间片算法。

系统把时间分成一份一份的,每个进入内存等待执行的进程都可以依次执行一段时间,在这段时间内未完成的进程放弃CPU的控制权让给下一个进程使用;如果在这期间进程执行完成或遇到阻塞,则挂起,操作系统得到挂起信号后即将CPU控制权移交给下一个进程,当然挂起的进程会被移动到进程列表的最后。

而Windows系统使用了抢占式的算法。

所谓抢占式,就是程序“霸占”了CPU的使用权,在它完成之前是不会放弃使用权的。

假设在内存中有很多排队等待的进程,操作系统会根据他们的优先级和等待时间计算出优先级,在下一次CPU空闲时,操作系统会把CPU使用权移交给优先级最高的进程。当这个进程执行完成或者主动挂起(遇到I/O等待、sleep等)后,操作系统会重复上面的操作。

再者如果进程长时间霸占CPU,操作系统监视到这种情况后,会使这个进程强制挂起。

sleep()方法

这个方法旨在告诉操作系统,某个进程在未来的一段时间内,不在参与CPU的使用竞争。操作系统在分配CPU时,自然会忽略掉使用sleep方法的进程。例如一个进程使用sleep方法后,一段时间后才会重新进入等待使用CPU的列表,但不代表这个进程会立即被唤醒,而是等待操作系统分配CPU使用而激活

结论

Thread.sleep(0)并不是一无是处,其作用是放弃CPU的使用权让操作系统中的其他等待进程一起立即再进行一次CPU的使用权竞争,这也给其他等待的进程执行的机会,使得资源分配更加合理,即使下一次获得使用权的还是这个进程。再者也是减少被CPU强制挂起的情况。

Java 多线程编程里,`Thread.sleep()` 是常用方法,它能让当前执行的线程暂停指定的时间(以毫秒为单位)。当参数为 0 时,也就是 `Thread.sleep(0)`,其行为和正数参数不同,有特殊用途 [^1]。 ### 作用 虽然 `Thread.sleep(0)` 看起来像是让线程暂停 0 毫秒,几乎不会离开 CPU,但实际上它能让当前线程主动放弃 CPU 时间片,促使操作系统重新进行 CPU 资源的分配。也就是说,调用 `Thread.sleep(0)` 后,当前线程会暂时让出 CPU,让操作系统重新调度,可能会把 CPU 分配给其他具有相同或更高优先级的线程 [^1][^2]。 ### 原理 操作系统会依据线程的优先级和调度算法来分配 CPU 时间片。每个线程都有机会获得 CPU 执行权,不过当某个线程在运行时,它会一直占用 CPU,直到时间片用完或者主动放弃。调用 `Thread.sleep(0)` 就是线程主动放弃当前时间片的一种方式。当线程调用 `Thread.sleep(0)` 时,它会告知操作系统“我现在可以让出 CPU 了,你重新进行调度吧”,接着操作系统会根据调度算法重新评估所有等待执行的线程,选择优先级最高的线程来执行 [^1][^2][^5]。 ```java public class SleepZeroExample { public static void main(String[] args) { Thread t1 = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); try { Thread.sleep(0); // 主动放弃 CPU 时间片 } catch (InterruptedException e) { e.printStackTrace(); } } }, "Thread-1"); Thread t2 = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); try { Thread.sleep(0); // 主动放弃 CPU 时间片 } catch (InterruptedException e) { e.printStackTrace(); } } }, "Thread-2"); t1.start(); t2.start(); } } ``` 在这个示例中,两个线程都会调用 `Thread.sleep(0)` 主动放弃 CPU 时间片,这样操作系统就有机会在两个线程之间切换执行。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值