我正在寻找有关在睡眠中期更改线程睡眠模式的信息。基本上这是我的情况......
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更新,并更改区间变量。
然而,当我更改它时,线程仍然处于休眠状态并将等待它完成,并在下一次迭代时更新。中断当前正在休眠的线程(或将其唤醒?)的最佳方法是什么?此外,我担心它会在生产服务器上运行时“安全”。
任何方向/指导都很棒。
答案 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分钟并检查是否是醒来或再次入睡的时间。在这种情况下,开销几乎没有。