java线程睡眠解析并等待同步块

时间:2012-06-19 05:26:49

标签: java multithreading sleep thread-sleep

我想了解更多关于线程睡眠分辨率如何工作的信息,以及除了sleep()的分辨率之外的其他内容。

我知道它是由操作系统定义的,而在Windows上它通常是15ms。我最近没有能够通过环顾四周来证实这一点,但我依旧回忆起这个15ms由操作系统循环并且对所有线程都是“全局的”,这意味着不是15ms是线程可以睡觉的最短时间,而是最大睡眠时间(1)。是对的吗?所有操作系统是否相同(超出持续时间)?

我无法想到这可能很重要的情况,但是在这个睡眠周期的动作点上是否会发生虚假的线程唤醒,或者它是否会在任何时间发生?

在同步块上,等待线程是否有效地休眠(1)-ing并在每个周期检查锁定,或者退出块的线程是否立即唤醒等待线程?所有操作系统都是一样的吗?

当线程在wait()之后发出通知() - 时,它会在等待锁定时以与上面相同的方式处理,还是不同?

从性能角度来看,还有其他时间15ms循环是否相关?

2 个答案:

答案 0 :(得分:4)

您需要对多线程内核进行一些研究。

'一个线程的虚假唤醒会在这个睡眠周期的动作点发生,还是会在任何时候发生?'

没有使用sleep()的虚假唤醒或任何内核同步对象在Windows上等待 - 根本没有。任何这样的趋势都已在内核中设计出来,并且不会传播到用户线程。

如果线程正在休眠或等待某个同步对象(如互斥锁或信号量锁),则它根本不运行 - 它只是内核中队列中的一个死的“线程描述符对象”,因此与所有线程相关在休眠的情况下,TDO位于所有超时线程的“增量队列”上,按唤醒时间排序,操作系统每隔15ms检查一次该队列头部的项目。在定时锁等待的情况下,TDO在两个队列上 - 超时队列和锁拥有的队列。 TDO将到达计时器队列的头部并在其间隔结束时准备就绪,或者另一个线程将释放锁并使线程准备就绪。无论哪个首先到达那里,都会获胜,并且TDO将从其他队列中删除。然后,新准备好的线程加入准备好的线程集,如果核心可用或者优先级较低的线程可以被抢占,则新准备好的线程将被分派到核心上。

因此,Windows上的“15ms”被所有线程“共享”。 Windows是一个桌面操作系统,15毫秒超出了人类的直接意识,因此99.9%的家庭线程不关心,因为它们只需要大量超时,等待I / O,等待一些线程间通信锁定或某些组合物。

'还有其他时间从性能角度看15ms循环是否相关?'

不多。计时器重新计划存在副作用,如果最高优先级可运行线程的集合大于可用于运行它们的核心数,则该集合以循环方式运行,因为这些线程的列表旋转了一圈。这仅适用于定期重载的计算机,大多数线程仅使用计时器间隔来超时阻止系统调用。

答案 1 :(得分:3)

Thread.sleep()实施取决于操作系统。

睡眠的粒度通常受线程调度程序的中断周期的约束。在Linux中,这个中断周期在最近的内核中通常为1ms(2.6.8以后)。在Windows中,调度程序的中断周期通常大约为10或15毫秒(我相信这是由处理器决定的),但可以在软件中请求更高的周期,Hotspot JVM在认为必要时会这样做。