我有一个经典的服务器/客户端问题,其中一个类正在定期等待来自服务器的数据更新。简而言之,我的程序如下:
public synchronized void eodProcess() {
//DO STUFF
dataReady = false;
while (!dataReady) {
try {
wait();
} catch (InterruptedException e) {
}
}
//DO STUFF
}
public void update(){
//CODE THAT DOWNLOADS FROM SERVER
synchronized(this){
dataReady = true;
notifyAll();
}
}
eodProcess()和update()都计划每天晚上在同一时间运行。
现在上面的代码一直可以工作,因为数据下载需要花费几秒钟,但是似乎做错了事,因为从理论上讲,update()的运行速度可能比eodProcess()快,将dataReady设置为true,然后eodProcess会设置将其设置为False,然后永远等待。确保eodProcess等待数据准备就绪的正确方法是什么?
我正在考虑安排一个新的进程,该进程将在两种方法中的任何一种之前几分钟将dataReady设置为false,并在eodProcess的开始处删除初始化,但这似乎不是很干净。
谢谢,
最佳答案
当应用CountDownLatch
很有用时,这是一种经典情况。
CountDownLatch downloadDone = new CountDownLatch(1);
[...]
public synchronized void eodProcess() {
//DO STUFF
downloadDone.await();
//DO STUFF
}
public void update(){
//CODE THAT DOWNLOADS FROM SERVER
downloadDone.countDown();
}
它基本上是一个信号量,但是更好。仅当锁存器递减至零(或线程被中断)时,才会进行等待。如果您需要重置计数的功能,请考虑使用
CyclicBarrier
(它的工作原理大致相同,但是有一个reset
方法)