Java定期唤醒阻塞线程

时间:2017-06-22 20:26:09

标签: java multithreading

我有一个程序,其中有几个线程写入缓冲区,并且有一个线程从缓冲区读取并写入文件。 缓冲区的实现方式是当缓冲区为空时尝试提取条目导致线程阻塞(使用wait())。 该线程使用BufferedStream写入文件。 目前,每写入10次文件后,我就会刷新BufferedStream。

while (true)
{
     BufferEntry entry = buffer.getEntry(); // might block

     logFile.printf("%s", entry);

     ++entriesWritten;

     if (entriesWritten >= 10)
     {
         logFile.flush();
         entriesWritten = 0;
     }
}

但是,我想介绍一种用例,其中在写入x个条目(x <10)之后,缓冲区长时间保持为空。 我希望缓冲区中剩余的条目超过一定的时间写入文件。

我正在考虑一个定期唤醒以处理刷新的守护进程,但是这样的守护进程意味着多个线程将处理一个文件,这是不可取的。更不用说守护进程必须知道当前未刷新的条目何时被写入......

我正在考虑使用中断方法并捕获InterruptedException。但是我担心这种方法并不漂亮,除了 - 写入文件时收到的中断可能会导致需要处理的不同类型的异常。

我也有一个想法是重载Buffer构造函数以接收一个额外的参数,这将使缓冲区等待指定的分钟数而不是永远。醒来后,可以检查是否需要冲洗。我对这个解决方案的关注是给缓冲带来一些不应该关注它的事情,以及等待没有返回指示的事实,关于它解除阻塞的原因。

有没有办法处理这种情况?

2 个答案:

答案 0 :(得分:0)

您可能需要查看Condition

此类提供对象监视器方法(waitnotifynotifyAll)的功能 - 它们被称为awaitsignal和{ {1}}以避免名称与从signalAll继承的方法发生冲突。

您可能感兴趣的是方法awaitNanos,因为它允许您指定超时:

  

使当前线程等待,直到发出信号或中断,或者指定的等待时间过去。

另一方面,也许简单的Object.wait(long timeout)可能足以满足您的使用案例。

答案 1 :(得分:0)

你说buffer.getEntry()来电Object.wait()。实现另一个调用buffer.getEntry(long timeout)的{​​{1}}方法,如果发生超时则返回null。

Object.wait(timeout)