【问题标题】:Java: Realizing periodic interruptions in code executionJava:实现代码执行的周期性中断
【发布时间】:2017-05-18 11:40:33
【问题描述】:

请建议以下伪代码的最佳实现:

“每隔 10 分钟打断你的业务逻辑并进入睡眠 5 分钟”

【问题讨论】:

  • 这应该在你的实现中实现Thread.sleep(5*60*1000);。
  • 等待()和睡眠()?
  • DimaSan,恕我直言,您的建议只会产生一个持续时间为 5 分钟的睡眠。我希望每执行 10 分钟后定期睡眠 5 分钟。

标签: java sleep


【解决方案1】:

解决方案

final long executionTimeSlice = 10 * 60 * 1_000_000_000;  // in nanoseconds
final long sleepDuration = 5 * 60 * 1_000;  // in milliseconds

while (true) {
    long endTime = System.nanoTime() + executionTimeSlice;

    while (System.nanoTime() < endTime) {
        /* execute stuff */
    }

    Thread.sleep(sleepDuration);
}

请注意,这取决于 /* execute stuff */ 能够分解为单独的迭代,每个迭代的预期持续时间都比 executionDuration 短(希望短得多)。


背景

理想的方法是使用守护线程,每 10 分钟 Thread#suspend 业务逻辑线程,然后在 5 分钟后 Thread#resume。像这样的:

final long executionTimeSlice = 10 * 60 * 1_000;  // in milliseconds
final long suspendedDuration = 5 * 60 * 1_000;  // in milliseconds
final Thread businessThread = Thread.currentThread();

Thread timerThread = new Thread(() -> {
        while (true) {
            businessThread.suspend();
            Thread.sleep(suspendedDuration);

            businessThread.resume();
            Thread.sleep(executionTimeSlice);
        }
});
timerThread.setDaemon(true);
timerThread.start();

很遗憾,Thread#suspend() 和 Thread#resume() 均已弃用。正如 Oracle 的this official statement 所示,

我应该使用什么来代替Thread.suspend 和Thread.resume?

...谨慎的方法是让“目标线程”轮询一个变量 指示线程的所需状态(活动或挂起)。当期望的状态被挂起时,线程等待...

【讨论】:

    【解决方案2】:

    您可以在无限循环内的子循环中执行您的逻辑。并在子循环中断条件下使用你的工作时间值:

    public static void main(String[] args) throws InterruptedException {
        final long WORKING_TIME = 10 * 60 * 1000;
        final long SLEEPING_TIME = 5 * 60 * 1000;
    
        long startTime;
        while (true) {
            startTime = System.currentTimeMillis();
            while (System.currentTimeMillis() < startTime + WORKING_TIME) {
                System.out.println("working..."); // implement your logic here
            }
            Thread.sleep(SLEEPING_TIME); // sleeping for SLEEPING_TIME
        }
    }
    

    【讨论】:

    • 非常感谢。对于我正在尝试做的事情,这是一个简单而优雅的解决方案(比我正在玩弄的计时器、多线程等简单得多)
    • 不客气!当然它很简单,但可能适合您的需求。
    猜你喜欢
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 2016-07-30
    • 1970-01-01
    • 2011-08-26
    • 2012-08-03
    相关资源
    最近更新 更多