Thread.sleep() 在内部是如何工作的?

11

假设我有一个线程T,它正在占用一个资源R。如果在当前线程即T上调用Thread.sleep(),那么它会在休眠之前释放资源R(以便让其他线程使用它)吗?还是它会保持该资源,并且当它醒来时再次使用资源R,在完成工作后才释放它?


1
你能更具体地说明一下你所说的资源示例吗? - jmj
3
一般而言,睡觉时不会释放任何资源。 - Jonathon Reinhart
@JigarJoshi,通常我会问同样的问题,但由于我知道sleep()不会关闭或释放_任何东西_,所以在这种情况下并不重要。程序员需要知道有关sleep(n)的所有信息就是它将阻塞调用者直到发生中断或经过n毫秒(以较早者为准)。除此之外,它什么也不做。 - Solomon Slow
5个回答

11
首先,Thread.sleep()是阻塞式的库方法。线程可能因多种原因而被阻塞或暂停:等待I/O完成、等待获取锁、等待从Thread.sleep中唤醒或等待另一个线程中的计算结果。当线程被阻塞时,通常会被挂起并置于其中一个已阻塞的线程状态。
因此,当您调用sleep()方法时,线程离开CPU并在一段时间内停止执行。在此期间,它不占用CPU时间,因此CPU可以执行其他任务。当线程正在睡眠并被中断时,该方法立即抛出InterruptedException异常,而不是等待睡眠时间结束。
Java并发API还有另一种使Thread对象离开CPU的方法。这是yield()方法,它向JVM指示Thread对象可以为其他任务离开CPU。JVM不保证会遵守此请求。通常,它仅用于调试目的。
关于sleep()最困惑的问题之一是它与object类的wait()方法有何不同
wait和sleep的主要区别在于,wait()方法在线程等待时释放获取的监视器,而Thread.sleep()方法即使线程等待时也保持锁定或监视器。

8

这篇Javamex文章中:

Thread.sleep()方法会暂停当前线程一段时间。我们在第一个线程示例中使用它来定期显示消息,并在消息之间休眠。重要的是要意识到以下几点:

  • 永远是当前线程被暂停;

  • 线程可能无法按照要求的时间(甚至根本不会)休眠;

  • 休眠持续时间将受到某些系统特定的粒度的影响,通常为1毫秒;

  • 在休眠时,线程仍然拥有已获得的同步锁;

  • 休眠可以被中断(有时用于实现取消函数);使用某些值调用sleep()可能会对操作系统产生一些微妙的全局影响(请参见下文),反之,系统上运行的其他线程和进程可能对观察到的休眠持续时间产生微妙的影响。


3

将要睡眠的线程在睡眠期间将保持锁定状态(不释放资源)。睡眠的线程甚至不会被调度,在它睡眠期间(或直到被中断并唤醒)。


1
如果你的资源R是Java监视器,那么释放它只有两种方式:
  • 退出同步块
  • 在拥有的监视器上调用wait方法

1

Javadoc 中写道 - sleep(): 使当前正在执行的线程在指定的毫秒数内休眠(暂停执行),具体取决于系统计时器和调度程序的精度和准确性。

Thread.sleep() 方法实际上与线程调度器交互,将当前线程置于等待状态,直到所需时间间隔结束。但是,该线程不会失去任何监视器的所有权。

为了允许中断,实现可能实际上并没有使用大多数操作系统提供的显式睡眠函数。

如果当前线程被阻塞在 Object 类的 wait()、wait(long)、wait(long, int) 方法或 Thread 类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法的调用中,则它的中断状态将被清除,并接收 InterruptedException 异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接