大家别激动,稍安勿躁。
阻塞的问题我也了解。另外先不纠结CPU多核的问题,while(true)长时间占满一个核我也是不同意的。while(true) sleep(1)我也了解,这里不说。
我的疑问是JDK中的延时线程池ScheduledThreadPoolExecutor,假设现在我设定了一个task需要到今晚零点执行,那底层是否应该就死循环,来判断当前时间是否是零点。
JDK中ScheduledThreadPoolExecutor源码如下,有for(;;)死循环:
public RunnableScheduledFuture<?> take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { RunnableScheduledFuture<?> first = queue[0]; if (first == null) available.await(); else { long delay = first.getDelay(NANOSECONDS); if (delay <= 0) return finishPoll(first); first = null; // don't retain ref while waiting if (leader != null) available.await(); else { Thread thisThread = Thread.currentThread(); leader = thisThread; try { available.awaitNanos(delay); } finally { if (leader == thisThread) leader = null; } } } } } finally { if (leader == null && queue[0] != null) available.signal(); lock.unlock(); } }
![]() | 1 looplj 2019-11-22 10:55:20 +08:00 代码呢。 |
![]() | 2 W1angMh 2019-11-22 11:05:30 +08:00 代码贴出来啊兄弟 |
3 Adlered 2019-11-22 11:11:58 +08:00 没代码说毛呢 |
![]() | 4 luckyrayyy 2019-11-22 11:14:42 +08:00 jdk 源码大量的死循环??? |
5 ivechan 2019-11-22 11:16:59 +08:00 2333,你该不会说得是类似下面这种死循环嘛? while(true) { recv(); } |
6 daozhihun 2019-11-22 11:17:31 +08:00 你确定 jdk 的死循环的线程不是在阻塞状态吗 |
7 cxtrinityy 2019-11-22 11:20:02 +08:00 via Android 先问是不是 |
![]() | 8 LuckyBoyGirl 2019-11-22 11:23:59 +08:00 你这个问题就类似 为何消费者也是用的 while(true) cpu 缺没有跑满 哈哈 |
![]() | 9 wutiantong 2019-11-22 11:28:22 +08:00 这种问题自己留着琢磨多好。 |
![]() | 10 lhx2008 2019-11-22 11:29:52 +08:00 via Android JDK 里面的死循环一般里面都带阻塞的 |
![]() | 11 tabris17 2019-11-22 11:31:01 +08:00 while(true) sleep(1) 你给我跑满 cpu 试试 |
![]() | 12 guolaopi 2019-11-22 11:31:19 +08:00 1.跟 debug 有关 2.人家的死循环是迫不得已的为了实现某种机制吧,比如 socket,代码中肯定包含终止循环的方法 3.不贴代码让人怎么猜 |
![]() | 13 henices 2019-11-22 11:34:02 +08:00 现在的 CPU 多是多核,一般情况只能将某个核给跑满,对整个系统影响其实不大。 |
![]() | 14 ExploreWay 2019-11-22 11:34:23 +08:00 ![]() 轮询超时机制限制,一般都会有吧! |
15 zivyou 2019-11-22 11:35:28 +08:00 循环体中有让线程挂起的地方 |
16 ffkjjj 2019-11-22 11:37:49 +08:00 首先, JDK 里面一般都是阻塞的 其次, 你试一下以下代码 cpu 占用的区别 while(true){ } while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { return; } } |
![]() | 17 sheep3 2019-11-22 11:44:51 +08:00 死循环一直算肯定跑满,你说的肯定有阻塞 |
![]() | 18 dosmlp 2019-11-22 11:55:00 +08:00 ![]() 说告诉你死循环=cpu 占用 100%的!!!?? |
19 XiLemon 2019-11-22 12:00:03 +08:00 via iPhone 说的是不是 cas 操作相关的代码 |
21 exip 2019-11-22 12:17:06 +08:00 via Android 人家那是有退出条件的死循环,你这是无条件的死循环. |
22 JingW 2019-11-22 12:21:02 +08:00 你 await 一下你也不占 CPU |
![]() | 24 ipwx 2019-11-22 13:07:35 +08:00 via Android 这种典型就是操作系统原理没学过才会发出的疑问。科班还是有科班的底蕴的。 |
![]() | 25 ipwx 2019-11-22 13:11:01 +08:00 via Android ![]() 这么说吧,线程占用 cpu 必须是在运行,而线程被操作系统调度才会被运行。因为 io 或者其他原因阻塞,线程会进入操作系统的等待队列,不会被运行。线程即使不进入阻塞,也不一定一直运行,操作系统随时可以打断线程,让它暂停,让渡资源给别的线程运行一段时间,再切换回来。当然资源充足情况下操作系统一般不会主动打断线程运行。 |
![]() | 26 opengps 2019-11-22 13:21:49 +08:00 via Android ![]() 死循环不可怕,可怕的是死循环内部不休息 |
![]() | 27 misaka19000 2019-11-22 13:26:47 +08:00 楼主基础堪忧 |
28 Raymon111111 2019-11-22 13:29:54 +08:00 死循环但并不占用 cpu 不知道这么讲能不能明白 |
![]() | 29 watzds 2019-11-22 13:30:36 +08:00 via Android 贻笑大方 |
![]() | 30 HypoChen 2019-11-22 13:42:09 +08:00 ![]() |
![]() | 32 enenaaa 2019-11-22 13:56:39 +08:00 楼主三年经验看不懂这个代码不应该啊。 |
![]() | 33 axwz88 2019-11-22 14:34:19 +08:00 via Android 楼主你这问题也太没水平了吧。。。 |
![]() | 34 onice 2019-11-22 15:19:52 +08:00 以前我在项目中实现生产和消费也出现过这个问题,最大的原因就在于没有用阻塞方法。 |
![]() | 35 realpg PRO ![]() 我觉得楼上的所有人对死循环的理解都有问题…… 那种能自身条件打断的不叫死循环吧…… |
36 mxT52CRuqR6o5 2019-11-22 15:36:18 +08:00 via Android 这不是被 try 包着,有异常就结束循环了,叫哪门子的死循环 |
![]() | 37 jeffh OP @php01 这我就不同意了,难道 while(true)时间就不切片了?我是科班出身,可能没大家牛 b 吧。 |
![]() | 38 jeffh OP @mxT52CRuqR6o5 #36 老哥,不能这么想啊,有异常就结束循环,如果人家程序就没异常呢。 |
![]() | 39 mccreefei 2019-11-22 16:15:55 +08:00 设定了一个 task 需要到今晚零点执行,不是会计算 delay,然后 awaitNanos(delay)。没有任务也会 await(),这里死循环怎么就 cpu100%了? |
![]() | 40 meik2333 2019-11-22 16:22:52 +08:00 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html#awaitNanos-long- 我不会 Java,使用 `RunnableScheduledFuture await` 关键词从 Google 搜到了上面的链接。 简单的猜测一下,你给出的代码和 `while(true) sleep(1)` 没有本质的区别,sleep 之后线程挂起,不再占用 CPU 资源,时间到了之后由操作系统通过信号唤醒。 |
41 NeroKamin 2019-11-22 16:28:39 +08:00 那么多 await 看不到吗 |
43 johnniang 2019-11-22 17:14:00 +08:00 via Android 顺便说一下,时间片是动态的,根据进程运行情况不断调整,而且操作系统会尽可能让 CPU 忙起来(尽管死循环会造成 CPU 空转)。 |
![]() | 44 nicebird 2019-11-22 17:37:25 +08:00 阻塞了呗。 sleep、锁、wait、poll 等操作,cpu 时间就切出去了。 |
![]() | 45 passerbytiny 2019-11-22 18:12:37 +08:00 @jeffh 感情你这是只认识 sleep,不认识 await。问问题急躁不是大问题别人会一边骂一边回答,但问完了还不认错就有问题了后面别人直接不鸟你。 |