我有一个经典的服务器/客户端问题,其中一个类正在定期等待来自服务器的数据更新。简而言之,我的程序如下:

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方法)

09-26 07:02