我目前遇到以下问题:
我制作了一个“缓存更新程序线程”,它会检查更新,然后休眠一段时间。我还构建了一个Button
,使用户可以手动检查更新。 Thread
的构建方式如下:
public static Thread cacheUpdater = new Thread(new Runnable() {
int milliSecondSleepTime = 10000;
public void run() {
try {
cacheUpdater.setPriority(Thread.MIN_PRIORITY);
//Infinite loop
while (!terminate) {
syncStatus.set(0);
//Check for updates with some methods, not important here.
syncStatus.set(1);
Thread.sleep(this.milliSecondSleepTime);
}
}
catch (InterruptedException e) {
//First check if it is termination time
if (!terminate) {
syncStatus.set(0);
this.run();
}
}
catch (Exception e) {
System.out.println(e);
}
return;
}
});
如果用户单击手动更新按钮,则会运行以下代码:
@FXML public void syncOnRequest() {
//Only call interrupt, because then it will start again when terminate is still false
CacheManager.cacheUpdater.interrupt();
System.out.println(CacheManager.cacheUpdater.getState().equals(State.TIMED_WAITING));
while (!CacheManager.cacheUpdater.getState().equals(State.TIMED_WAITING)) {
//LOOP FOREVER
}
//Some code that needs to be executed after the cache is updated
}
当缓存更新程序准备好进行手动更新时,我想继续在syncOnRequest()
方法中执行代码。我有想法检查它是否正在睡眠,但这不起作用,因为System.out.println()
立即返回true。我已经测量了进行更新所需的时间,以及200到400毫秒之间的时间。
我在这里做错了什么?为什么它总是回归真实?
其他问题:有时单击该按钮会导致Thread
被杀,因为它刚刚醒来。 InterruptedException
未被抛出。
在这种情况下,如何确保Thread
也会重启?
答案 0 :(得分:2)
请注意,Thread#interrupt()
是要求线程自行中断的唯一礼貌方式(除非您明确实现另一个)。因此,使用它来重新启动检查是一种不好的做法。因此,检查线程状态是否有同步目的,并将使缓存保持最新的线程暴露给外部客户端。
您的经理应该有一个updateCache()
方法,您将直接从UI代码调用,自动更新线程将定期调用相同的方法*。在该方法中,确保对缓存数据的访问正确同步或以原子方式发生。
*)不要实现自己的定期线程,而是考虑使用
Timer
and TimerTask
类以及使其成为守护程序线程。