当Java线程执行可能的阻塞操作时,它是否总是丢失当前的CPU时间片?

时间:2017-03-01 10:23:42

标签: java multithreading scheduler

可能阻塞的操作(例如Thread.join(),obj.wait(),monitorEnter)可能会在某些情况下继续执行(例如For Thread.join(),如果中断标志是在时间设置的话调用时,方法不会阻塞。对于obj.wait(),如果设置了中断标志并且监视器可用,则动作不会被阻止)。在这种情况下,java线程会继续在当前的CPU时间片中;或者它会释放当前的时间片并等待下一次发送?

3 个答案:

答案 0 :(得分:1)

无法保证它会丢失CPU,也不能保证它会在整个时间段内被阻止;

  • 可以立即执行操作。
  • 操作可能会在放弃CPU之前等待很短的时间,但可能会在那段时间内完成。
  • 线程可能会在时间片内恢复CPU。

这完全取决于操作系统。繁忙的等待策略有时用Java实现,在这种情况下,您将在源代码中看到它。

答案 1 :(得分:1)

你的问题有点困惑 - 一个线程只能在已拥有监视器的情况下调用wait。通过输入同步块并通过monitorEnter进程获取。

但是要尝试回答你的问题:如果一个线程调用一个潜在的阻塞动作(即,需要获取对象监视器),它是否总会丢失时间片?答案是不。它将首先尝试一些“快速路径”尝试,然后才会停止线程。

监视器同步的代码位于:http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp#l1192

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实现可能会忽略您的提示。