我有一个典型的服务器/客户端问题,其中一个类正在等待来自服务器的数据定期更新。简而言之,我的计划如下:
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开头的初始化,但这看起来并不干净。
谢谢,
答案 0 :(得分:1)
这是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();
}
它基本上是一个信号量,但更好。 Await仅在锁存器倒计数到零(或线程中断)时才会继续。如果您需要重置计数的功能,请考虑使用CyclicBarrier
(它的工作方式大致相同,但有reset
方法)