⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/M283592338/article/details/106819349 「问题不太大」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

今天看到一段有意思的代码:Thread.sleep(0),下面就来分析一下这串看似无用的代码到底有没有用。

Thread.sleep(0)到底是个什么骚操作,这睡0毫秒和不睡有什么区别吗?

操作系统资源的分配策略

想要去了解多线程,就先要去了解操作系统中资源的不同分配策略。在操作系统中,CPU资源的分配策略有多种,下面就拿两种最为典型的策略举例:

时间片算法

基于时间片算法分配资源的代表就是Unix系统。在时间片算法中,操作系统会维护一个队列,将所有的进程放入队列中。然后操作系统会按照队列中的进程顺序为他们分配属于自己的运行时间,也就是说,操作系统给A进程分配n毫秒时间,那么A进程在本次排队时只可以运行n毫秒。

当A进程运行完n毫秒后,操作系统不管A是否运行完毕都会把运行权限强行剥夺,交给队列里面的下一个进程去执行,然后A进程继续去队列尾部进行下一次排队。(这里,如果A在n毫秒之前提前结束或者被阻塞,操作系统会立即收回A的运行权限)

举个例子:

你去食堂买饭,这种模式就是食堂会强制你去排队,而且每人只有十分钟点餐时间,一旦过了这个时间你就要重新去排队。

抢占式

基于抢占式分配资源的代表是Winodws系统。抢占式的操作系统都是“儒家学派”的,默认每个进程都是“君子”。意思就是:一个进程一旦拿到CPU后,除非它主动放弃CPU权限,不然别的进程是拿不到CPU权限的。

然后操作系统在选取执行权限的时候也不是随机选的,它会根据优先级和饥饿时间来判定谁更需要CPU权限的。每次一个进程是释放CPU后,就会进行一次优先级评定。也就是说,如果运气好,每次都会被选中。

举个例子:

你去食堂买饭,食堂阿姨看你小伙子挺帅就先给你盛饭。然后给你盛完饭再选一次,又发现你这小伙子越看越顺眼,就再给你一碗。

关于Sleep

拿抢占式来说。去食堂吃饭,阿姨看小伙子挺不错,三番五次的给你盛饭,但是你已经吃饱了,这时候你就会告诉阿姨我吃饱了,接下来半小时不要再给我盛饭了。

对应到代码里就是,A最近30min不想再参与资源选举了,这时它就会sleep(30 * 60 * 1000),然后操作系统就会进行再次选举,并且未来半小时A不参与选举。此时当A醒来之后,或许CPU执行权在另一个进程手里。

再说Thread.sleep(0)

假如A执行了一段时间后,突然想起来其他小伙伴可能也需要CPU执行权限,不能光自己一个人霸占这个CPU,但是又没办法主动申请再次选举,就只能退而求其次执行Thread.sleep(0),在A有执行权限的情况下执行,执行后告诉操作系统,我要休息0毫秒,你接下来0毫秒内的选举就不要选我啦。但是操作系统下次再选举的时候还是会把A算进去,因为0毫秒已经过了。

总结

Thread.sleep(0)不光有用,而且有奇效,对于想做老好人的进程可以调用一次,让操作系统再次进行选举。

文章目录
  1. 1. 操作系统资源的分配策略
    1. 1.0.1. 时间片算法
    2. 1.0.2. 抢占式
  • 2. 关于Sleep
    1. 2.0.1. 再说Thread.sleep(0)
  • 3. 总结