在Java中是否有Thread.sleep的替代方法?

3

这是我的代码

while (true) {
    try {
        Thread.sleep(5 * 60 * 1000);
        processData();// data processing job
    } catch (InterruptedException e) {
        SystemMessageBillPay.getInstance().writeMessage("ERROR: CEB.run() - " + e.getMessage());
    } catch (NumberFormatException e) {
        SystemMessageBillPay.getInstance().writeMessage("ERROR: CEB.run() - " + e.getMessage());
    }
}

对于以下代码:

"Thread.sleep(5 * 60 * 1000);"

代码检查器会发出警告:

"在循环中调用Thread.sleep可能会导致性能问题"

为了避免这个警告,应该使用以下代码:

"TimeUnit.MINUTES.sleep(5);"

这个代码不仅更易读,而且更加高效。


1
不要使用无限循环和睡眠来定期运行作业,而是使用例如ScheduledExecutorService来安排任务每5分钟执行一次。 - Jesper
我已经更改了重复的内容,因为原始链接讨论的是忙等待而不是想要睡觉。 - Peter Lawrey
你的代码确实存在一个严重问题:如果 sleep() 被中断,processData() 就不会被调用。如果这种情况经常发生,你的工作就无法完成。而最好的答案取决于你想让你的代码做什么。每五分钟准确运行而没有偏差?大约每五分钟运行,有时更快? - Andrew Henle
1
有趣的是,到目前为止提供的替代方案并没有解释它们实际解决的性能问题。因此,它们只是实现类似功能的不同方式。 - David Soroko
4个回答

8

在1.8版本中,你也可以使用以下方法:

import java.util.concurrent.locks.LockSupport;

LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(1000));

根据Javadoc的说明:
禁用当前线程进行线程调度,最多等待指定的时间,除非许可证可用。
好处是,它的签名不会抛出已检查异常。因此,您不必尝试捕获(与Thread.sleep不同,后者需要处理InterruptedException)。当然,它们都有各自适用的用途。

请注意parkNanos()周围的多个警告,例如“调用可能会出现虚假返回(即无原因返回)”。 - Brian Agnew

2
Is there a alternative to Thread.sleep
是的,有方法。但是,
看起来你想要安排一些工作。你可以使用TimerTaskScheduledExecutorService代替这个。所以你问题的后半部分是关于
"在循环中调用Thread.sleep可能会导致性能问题"
并且这将通过安排任务来解决。
安排任务。
public class Test extends TimerTask{

public static void main(String[] args) {
  Test task = new Test();
  Timer timer = new Timer();
  Calendar today = Calendar.getInstance();
  today.set(Calendar.HOUR_OF_DAY, 13);
  today.set(Calendar.MINUTE, 47);
  today.set(Calendar.SECOND, 0);
  timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
}

 @Override
public void run() {
 System.out.println("Running Scheduled Task...!!!");
}
}

1
请不要再使用Calendar对象,而是使用新的(Java 8+)时间API类。 - Brian Agnew

0
你需要使用一个秒表计时器来完成这个任务,而不是使用线程。可以使用这个:org.apache.commons.lang.time.StopWatch,它在这里有详细的描述:http://commons.apache.org/lang/

0

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