【问题标题】:How Thread.sleep() works internallyThread.sleep() 如何在内部工作
【发布时间】:2014-06-23 05:35:14
【问题描述】:

假设我有一个线程 T,它持有一个资源 R。如果我在当前线程(即 T)上调用 Thread.sleep(),它会在去之前释放资源 R(让其他线程使用它)吗?睡不睡? 或者它将持有该资源,并在它醒来时再次使用资源 R 并在完成工作后释放它?

【问题讨论】:

  • 您能否更具体地说明您的资源示例
  • 一般来说,没有。进入睡眠状态时不会释放任何资源。
  • @JigarJoshi,通常我会问同样的问题,但因为我知道 sleep() 不会关闭或释放 anything,所以这并不重要案子。程序员需要知道的关于 sleep(n) 的所有信息是,它将阻塞调用者,直到发生中断,或经过 n 毫秒(以较早者为准)。除此之外,它不会做任何其他事情。

标签: java multithreading concurrency


【解决方案1】:

首先,Thread.sleep() 是阻塞库方法。线程可能会因为以下几个原因而阻塞或暂停:等待 I/O 完成、等待获取锁、等待从 Thread.sleep 中唤醒或等待另一个线程中的计算结果。当一个线程阻塞时,它通常被挂起并处于阻塞线程状态之一。

所以,当你调用 sleep() 方法时,线程离开 CPU 并停止它的 执行一段时间。在此期间,它不消耗 CPU 时间, 因此 CPU 可以执行其他任务。当线程处于睡眠状态并且正在 中断,该方法立即抛出 InterruptedException 异常 并且不会等到睡眠时间结束。

Java 并发 API 有另一个方法可以让 Thread 对象离开 CPU。它是 yield() 方法,它向 JVM 指示 Thread 对象可以离开 CPU 执行其他任务。 JVM 不保证它会遵守这个请求。通常,它仅用于调试目的。

与 sleep() 的混淆之一是 它与对象类的 wait() 方法有何不同

wait 和 sleep 的主要区别在于 wait() 方法在线程等待时释放获取的监视器,而 Thread.sleep() 方法在线程等待时保持锁或监视器。

【讨论】:

    【解决方案2】:

    来自this Javamex article

    Thread.sleep() 方法有效地“暂停”当前线程一段给定的时间。我们在第一个 threading example 中使用它来让线程定期显示消息,在消息之间休眠。从一开始,重要的是要注意以下几点:

    • 总是当前线程进入睡眠状态;

    • 线程可能没有休眠所需的时间(甚至根本没有);

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

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

    • 可以中断睡眠(有时对于实现 取消功能);使用某些值调用 sleep() 可以 对操作系统的一些微妙的全局影响(见下文),反之亦然, 系统上运行的其他线程和进程可能具有微妙的 对观察到的睡眠时间的影响。

    【讨论】:

      【解决方案3】:

      将要休眠的线程在休眠时将持有锁(not release resource)。一个休眠的线程甚至不会被安排在它休眠的时间(或者直到它被中断然后唤醒)

      【讨论】:

        【解决方案4】:

        如果你的资源R是java监视器,那么释放它的方法只有两种:

        • 退出synchronized
        • 在自有显示器上调用 wait

        【讨论】:

          【解决方案5】:

          Javadoc 说 - sleep(): 使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精度和准确性

          Thread.sleep() 方法本质上与线程调度程序交互,以在所需的时间间隔内将当前线程置于等待状态。但是,该线程不会失去任何监视器的所有权。

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

          如果当前线程在调用wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int)methods of Thread class时被阻塞,则其中断状态将被清除,并会收到一个InterruptedException。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-03-13
            • 2019-01-13
            • 2010-10-14
            • 2013-09-28
            • 2012-08-01
            • 2011-12-10
            • 2018-02-10
            相关资源
            最近更新 更多