可能阻塞的操作(例如Thread.join(),obj.wait(),monitorEnter)可能会在某些情况下继续执行(例如For Thread.join(),如果中断标志是在时间设置的话调用时,方法不会阻塞。对于obj.wait(),如果设置了中断标志并且监视器可用,则动作不会被阻止)。在这种情况下,java线程会继续在当前的CPU时间片中;或者它会释放当前的时间片并等待下一次发送?
答案 0 :(得分:1)
无法保证它会丢失CPU,也不能保证它会在整个时间段内被阻止;
这完全取决于操作系统。繁忙的等待策略有时用Java实现,在这种情况下,您将在源代码中看到它。
答案 1 :(得分:1)
你的问题有点困惑 - 一个线程只能在已拥有监视器的情况下调用wait。通过输入同步块并通过monitorEnter进程获取。
但是要尝试回答你的问题:如果一个线程调用一个潜在的阻塞动作(即,需要获取对象监视器),它是否总会丢失时间片?答案是不。它将首先尝试一些“快速路径”尝试,然后才会停止线程。
VM首先尝试非常快速的原子CAS操作来获取监视器。如果失败则尝试短暂的自旋锁(以保持CPU)。如果自旋锁失败则会停止线程。
公园在Windows下发生:http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/os/windows/vm/os_windows.cpp#l4787
它看起来像是调用Windows WaitForSingleObject API函数。
答案 2 :(得分:0)
如果执行anotherThread.join()
并且anotherThread
已完成,则不会丢失CPU时间片。同样,如果执行了monitorEnter obj
,并且obj
未被锁定,则执行将继续而不会中断。
如果您故意想要释放当前时间片并等待下一次调度,请调用Thread.yield()
或Thread.sleep(0)
,但JVM实现可能会忽略您的提示。