如何在Java中正确使用thread.sleep()?

时间:2015-03-18 06:39:38

标签: java

我在代码库中看到了很多代码片段:

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

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

我想知道我的代码中是否存在中断线程的逻辑,JVM是否可以中断正在休眠的线程?如果是这样,如何确保线程休眠到指定时间段的末尾?

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

1 个答案:

答案 0 :(得分:0)

由于评论已经链接到问题的答案,为什么你应该捕获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保留对线程获取的监视器的锁定也很重要。这意味着您可以在同步块中使用它,并期望线程能够在睡眠返回后继续它在此块中所做的工作(当然,如果线程没有被中断)。