【问题标题】:How to use thread.sleep() properly in Java?如何在 Java 中正确使用 thread.sleep()?
【发布时间】:2015-05-20 20:35:41
【问题描述】:

我在我们的代码库中看到下面很多代码sn-ps:

        try {
            Thread.sleep((int)Millis);
        } catch (InterruptedException e) {
        }

显然,空的 catch 子句不是一个好主意。如果线程被中断,睡眠周期不会完全结束。

我想知道我的代码中是否没有逻辑可以中断线程,JVM 是否可以中断正在休眠的线程?如果是这样,如何确保线程休眠到指定周期结束?

使用thread.sleep() 方法的最佳做法是什么?

【问题讨论】:

  • 如果你在乎,答案也取决于事实。如果您不关心线程在从睡眠状态返回之前是否被中断,则无需担心。另一方面,如果睡眠后的代码依赖于睡眠完成(或线程的状态),那么您应该监控异常
  • 在询问如何正确地围绕它们进行编码之前,我会先问一下睡眠在那里做了什么。一个正确编写的应用程序根本不需要休眠。

标签: java


【解决方案1】:

由于 cmets 已经链接到关于为什么应该捕获 InterruptedException 的问题的答案,我将专注于您的第二个问题 - 关于 Thread.sleep() 的使用。

当你想在你的线程执行中引入一个短暂的暂停时,这个方法很方便。例如,假设您必须更新数据库中的 100 000 行,但为了降低对数据库的影响,您需要在更新查询之间引入间隔,例如 2 秒。一种快速而简单的解决方案如下所示:

for (int i = 0; i < 100 000) {
   statement.executeUpdate(....);
   Thread.sleep(2000);
}

在每次更新后等待 2 秒,然后再执行下一次更新。 (请记住,这只是概念的说明,而不是要复制粘贴的完整的生产就绪代码)。

当您等待某些资源可用并且不想在等待其可用时浪费 CPU 周期时,会发生另一种典型情况。例如,您进行了一个返回 Future 的异步调用,并且您希望等待异步计算完成以继续您的逻辑。它通常是这样完成的:

    int someNumberOfMillisToSleep = //some number;
    ...

    while (!future.isDone()) {
        Thread.sleep(someNumberOfMillisToSleep );
    }

    /*now that future.isDone() returned true, 
you can get the result and go on with on with you logic
   */ 
    int res = future.get();

    //some computation here

因此,您无需等待异步计算完成就睡觉,以免在 CPU 上产生无用的负载。

同样重要的是,与wait 相比,sleep 方法保留了线程获取的监视器上的锁。这意味着您可以在同步块中使用它,并期望线程能够在睡眠返回后继续它在此块中所做的工作(当然,如果线程没有被中断)。

【讨论】:

    猜你喜欢
    • 2018-09-27
    • 2019-06-20
    • 2018-09-25
    • 2017-02-19
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多