2017-06-22 1 views
2

私は、いくつかのスレッドがバッファに書き込んでおり、バッファから読み込んでファイルに書き込むスレッドが1つあるプログラムを持っています。 バッファは、バッファが空のときにエントリを抽出してスレッドをブロックする(wait()が使用される)ように実装されています。 スレッドは、BufferedStreamを使用してファイルに書き込みます。 現在、ファイルが書き込まれるたびにBufferedStreamをフラッシュしています。定期的にスレッドをブロックするJavaを目覚めさせる

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

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

    ++entriesWritten; 

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

ただし、IはXのエントリ(X < 10)を書き込んだ後、バッファが長時間空のままであるユースケースをカバーしたいと思います。 バッファに残っているエントリが一定時間以上ファイルに書き込まれるようにしたいと思います。

私は、フラッシングを処理するために定期的にウェイクアップするデーモンについて考えていましたが、そのようなデーモンは複数のスレッドがファイルを処理することを意味しますが、これは望ましくありません。デーモンは、現在のフラッシュされていないエントリがいつ書き込まれたのかを知る必要はありません。

私は割り込みメソッドを使用し、InterruptedExceptionをキャッチすることを考えていました。しかし、私はこのアプローチがきわめて簡単ではないことを恐れています。ファイルに書き込むときに受け取った割り込みは、処理が必要な異なる種類の例外を引き起こす可能性があります。

また、バッファコンストラクタをオーバーロードして、バッファが永久にではなく指定された分だけ待機するようにする追加のパラメータを受け取ることをお勧めします。目を覚ますと、フラッシュが必要かどうかを確認することができます。このソリューションの私の懸念は、Bufferに懸念すべきではないものと、waitがブロック解除の理由を示すものではないという事実をBufferに負わせています。

このような状況を処理するにはかなりの方法がありますか?

答えて

0

あなたはCondition

このクラスに見てみたいことは、オブジェクトのモニター・メソッド(waitnotifynotifyAll)の機能を提供しています - 彼らが名前の衝突を避けるためにawaitsignalsignalAllと呼ばれていますObjectから継承したメソッド。

はそれが指定された待機時間が経過合図または中断、またはされるまで、現在のスレッドを待機させ:それはあなたがタイムアウトを指定することができますよう

は、あなたが興味を持つであろうことは、方法awaitNanosです。

一方、おそらく単純なObject.wait(long timeout)で十分です。

+0

私はLock and Conditionを使用することをお勧めします。 Conditionのメソッドawaitは、タイムアウトによってスレッドが起きたかどうかを示すブール値を返します。タイムアウトを受け取るためにgetEntryをオーバーロードするアレクセイの提案とともに、Bufferオブジェクトを一般的に十分に保ちながら、問題を解決するには良い方法かもしれません。ありがとう! – Victoriia

0

buffer.getEntry()Object.wait()と表示されています。別のメソッドbuffer.getEntry(long timeout)を実装して、Object.wait(timeout)を呼び出し、タイムアウトが発生した場合はnullを返します。

 BufferEntry entry = buffer.getEntry(timeout); // might block 

    if (entry != null) { 
     logFile.printf("%s", entry); 
     ++entriesWritten; 
    } 

    if (entriesWritten >= 10 || entry == null) { 
     logFile.flush(); 
     entriesWritten = 0; 
    } 
+0

私はあなたのアイデアがgetEntryメソッドをオーバーロードするのが好きです。このように、Bufferは追加サービスを提供するだけで十分な汎用性があります。 APIドキュメントでは、オブジェクトのwaitメソッドが、スレッドがタイムアウトにより起動されたことを示すことはありません。私はロックとコンディションを使用するというHulkの提案を、あなたと一緒に使うことで、メソッドをオーバーロードして素晴らしい解決策を作ると思います。ありがとう – Victoriia

関連する問題