- 背景
最近工作中碰到一个问题
测试系统稳定性的时候发现 CPU 一直爆满
经过多方面排查 发现是多处用了while(true)
- 处理办法
在while(true) 的代码中加一个 Thread.sleep(1)即可
- 事后思考
为什么呢 那就得回顾一下操作系统相关的知识
操作系统的 CPU 现在可能有四核、八核、16核 但是我们打开tomcat线程数一看有120多
那么操作系统的 CPU 就要有正确的调度规则 , 操作系统中有很多算法 Unix系统使用的是时间片算法,而Windows则属于抢占式的。
在时间片算法中,所有的进程排成一个队列。操作系统按照他们的顺序,给每个进程分配一段时间,即该进程允许运行的时间。如果在 时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则 CPU 当即进行切换。调度程 序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。
所谓抢占式操作系统,就是说如果一个进程得到了 CPU 时间,除非它自己放弃使用 CPU ,否则将完全霸占 CPU 。因此可以看出,在抢 占式操作系统中,操作系统假设所有的进程都是“人品很好”的,会主动退出 CPU 。
在抢占式操作系统中,假设有若干进程,操作系统会根据他们的优先级、饥饿时间(已经多长时间没有使用过 CPU 了),给他们算出一 个总的优先级来。操作系统就会把 CPU 交给总优先级最高的这个进程。当进程执行完毕或者自己主动挂起后,操作系统就会重新计算一 次所有进程的总优先级,然后再挑一个优先级最高的把 CPU 控制权交给他。
回到我们的问题 我们如果写一个while(true) 而不加线程睡眠,那么此线程告诉操作系统的是 我要一直占用资源
如果写一个Thread.sleep(0) ,那么告诉操作系统的是 我可以让出资源给其他人 但是是给优先级比我高的 这样修改有效果 但是不是很明显
如果写一个Thread.sleep(1), 那么告诉操作系统的事 我可以让出资源 并且休息1ms 这样优先级低的也可以持有资源了
那么提出一个疑问 我在 2022-01-19 02:00:00,000 休眠线程 写一个Thrad.sleep(1000) ,那么在一秒后真的会继续执行嘛,答案是否定的一秒后 如果有其他资源还在持有CPU资源 就不会执行。当然这个会很快
所以以后的大循环 甚至 while(true) 建议加一个 Thread.sleep(1) 这样不会一直持有资源