如何更改已经休眠的Thread.sleep()的持续时间

时间:2015-06-24 16:57:43

标签: java multithreading

我正在寻找有关在睡眠中期更改线程睡眠模式的信息。基本上这是我的情况......

public void run() {
    while(running) {
        //Update Stuff...
        try {
            long time = System.currentTimeMillis() + interval;
            String dateFormatted = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss a").format(new Date(time));
            Thread.sleep(interval);
        } catch (InterruptedException e) {
            //Handle Errors...
        }
    }
}

所以我正在做的是在程序启动时,它将占用间隔(当前为60000),但是GUI具有能够改变间隔的选项(例如1小时,2小时,3等)。我可以从GUI更新,并更改区间变量。

然而,当我更改它时,线程仍然处于休眠状态并将等待它完成,并在下一次迭代时更新。中断当前正在休眠的线程(或将其唤醒?)的最佳方法是什么?此外,我担心它会在生产服务器上运行时“安全”。

任何方向/指导都很棒。

2 个答案:

答案 0 :(得分:2)

您可以通过wait / notify实现一个简单的解决方案。

这样的事情:

class DurationSleeper {

    private final Object monitor = new Object();
    private long durationMillis = 0;

    public DurationSleeper(long duration, TimeUnit timeUnit) {
        setDuration(duration, timeUnit);
    }

    public void sleep() {
        long millisSlept = 0;

        while (true) {
            synchronized (monitor) {
                try {
                    long millisToSleep = durationMillis - millisSlept;
                    if (millisToSleep <= 0) {
                        return;
                    }
                    long sleepStartedInNanos = System.nanoTime(); // Not using System.currentTimeMillis - it depends on OS time, and may be changed at any moment (e.g. by daylight saving time)
                    monitor.wait(millisToSleep);
                    millisSlept += TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - sleepStartedInNanos);
                } catch (InterruptedException e) {
                    throw new RuntimeException("Execution interrupted.", e);
                }
            }
        }
    }

    public void setDuration(long newDuration, TimeUnit timeUnit) {
        synchronized (monitor) {
            this.durationMillis = timeUnit.toMillis(newDuration);
            monitor.notifyAll();
        }
    }
}

答案 1 :(得分:0)

我不会使用interrupt(),更像是分开睡眠,让我们说1分钟并检查是否是醒来或再次入睡的时间。在这种情况下,开销几乎没有。