我想更多地了解线程休眠解析是如何工作的,以及除了sleep()的解析之外,它还与什么绑定在一起。
我知道它是由操作系统定义的,而在Windows上它通常是15ms。我最近还没能确认这一点,但我依稀记得这个15ms是由操作系统循环的,对所有线程都是“全局”的,这意味着线程可以休眠的最短时间不是15ms,而是最大休眠时间(1)。是那么回事吗?是否对所有操作系统都是相同的(超出持续时间)?
我想不出这种情况会有什么影响,但是一个虚假的线程唤醒总是会在这个睡眠周期的动作点发生吗,或者它会在任何时候发生吗?
在同步的块上,等待线程是有效地休眠(1)-ing并在每个周期检查锁,还是退出块的线程立即唤醒等待的线程?这对所有操作系统都是一样的吗?
当线程在-ed()之后被通知等待时,它是以与上面相同的方式处理,还是以不同的方式处理?
从性能的角度来看,是否还有其他时间与15ms环路相关?
发布于 2012-06-19 14:52:33
你需要对多线程内核做一些研究。
‘线程的虚假唤醒是否总是发生在这个睡眠周期的动作点,或者它会在任何时候发生?’
没有使用sleep()的虚假唤醒,也没有任何内核同步对象在Windows上等待-根本没有。任何这样的趋势都是在内核中设计出来的,不会传播到用户线程。
如果线程正在休眠或等待某个同步对象,如互斥量或信号量锁,它根本不会运行-它只是内核队列中的一个死线程描述符对象,因此所有与线程相关的东西,堆栈的数据空间等。在休眠的情况下,TDO在所有超时线程的‘增量队列’上,按唤醒时间排序,操作系统每隔15ms检查该队列头部的项。在定时锁等待的情况下,TDO在两个队列上-超时队列和锁拥有的队列。要么TDO将到达计时器队列的头部,并在其间隔到期时准备就绪,要么另一个线程将释放锁并使线程准备就绪。无论哪一个先到达,都会获胜,并且TDO将从另一个队列中删除。然后,新就绪线程加入该组就绪线程,并且如果内核可用或者较低优先级线程可以被抢占,则将新就绪线程分派到该内核上。
因此,Windows上的“15ms”由所有线程“共享”。Windows是一个桌面操作系统,15ms超出了人类的直接感知,所以99.9%的家庭线程并不关心,因为它们只需要很大的超时,正在等待I/O,正在等待一些线程间通信锁定或它们的组合。
“从性能的角度来看,15ms的循环是否还有其他时间是相关的?”
不是很多。定时器重新调度的副作用在于,如果最高优先级可运行线程的集合大于可用于运行它们的核心的数量,则该集合以循环方式运行,因为这些线程的列表是循环的。这只与定期过载的机器相关,并且大多数线程只使用计时器间隔来超时其他阻塞的系统调用。
发布于 2012-06-19 13:36:30
Thread.sleep()的实施取决于操作系统。
休眠的粒度通常受线程调度器的中断周期的限制。在Linux中,在最近的内核(2.6.8以后的版本)中,这个中断周期通常是1ms。在Windows中,调度器的中断周期通常在10或15毫秒左右(我认为这是由处理器决定的),但可以在软件中请求更长的周期,Hotspot JVM会在它认为必要时这样做。
https://stackoverflow.com/questions/11094857
复制相似问题