2016-10-31 8 views
2

背景

私はWebSocketの接続を介して受け取った最近のメッセージのコレクションが含まれているApacheのCommonsのライブラリからCircularFifoBufferクラスを使用しようとしています。しかし、LinuxデプロイメントでCircularFifoBufferのサイズ制限に達すると、BufferOverflowExceptionがスローされています。のApache Commonsの - CircularFifoBuffer BufferOverflowException

私はまだJavaのにかなり新しいですが、ここで私はCircularFifoBufferインスタンス変数を定義しています方法は次のとおりです。

private static Buffer<String> recentWebSocketMessages = new CircularFifoBuffer<String>(1000); 

そして、ここでは例外です:

org.apache.commons.collections15.BufferOverflowException: The buffer cannot hold more than 1000 objects. 
at org.apache.commons.collections15.buffer.BoundedFifoBuffer.add(BoundedFifoBuffer.java:218) 
at org.apache.commons.collections15.buffer.CircularFifoBuffer.add(CircularFifoBuffer.java:94) 
at com.example.SystemMonitor.putRecentWebSocketMessage(SystemMonitor.java:228) 

私には奇妙な何この問題がされています間欠的に、無限ループを書くとき:

while(true) 
{ 
    recentWebSocketMessages.add("TESTING"); 
} 

例外で発生していない - だから私はこの問題は断続的であると私は解決することができ、なぜここでの主な問題はあると思います(少なくとも、Windowsで、私はまだLinuxのをテストすることができていない)

質問

を代わりに静的変数をそのように定義することで(この緊密カップルBoundedFifoBufferCircularFifoBuffer実装とrecentWebSocketMessagesにもかかわらず)

private static CircularFifoBuffer<String> recentWebSocketMessages = new CircularFifoBuffer<String>(1000); 

編集

はありがとうは、この実装は同期化されていないという単純な事実を指摘しsorifiendとトム。興味のある方のために、以下のこの単純なスレッドの例では、マルチスレッドの問題であると同時に、バッファにアクセスする複数のスレッドが/ BufferOverflowExceptionは(バッファの私の元の定義で)発生する原因となりますことを証明している:

while(true) 
{ 
    new Thread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      try 
      { 
       recentWebSocketMessages.add("TESTING"); 
      } 
      catch(BufferOverflowException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    }).start(); 
} 

Buffer recentWebSocketMessages = BufferUtils.synchronizedBuffer(new CircularFifoBuffer(1000)); 
+2

[* "この実装は同期されていません。" *] /CircularFifoBuffer.html)...おそらくあなたの問題です。 – Tom

答えて

2

クイック答えは:いいえ、そのようにそれを変更して文句を言わない本当に役立つrecentWebSocketMessagesの次の定義と同じコードがAPIにし、sorifiendの答えで述べたように、バッファへのアクセスが同期されるので、BufferOverflowExceptionスローしません。項目は自動的にスペースを追加するために除去しなければならないので

テストメッセージは、問題を引き起こす習慣:

CircularFifoBufferは完全な場合は、その最古要素を置き換える固定サイズ と出て最初のバッファの最初のです。

CircularFifoBufferの削除順序は、挿入 の注文に基づいています。要素は、 が追加されたのと同じ順序で削除されます。反復順序は削除順序と同じです。

しかし、バッファ制限(1000の場合)のときに、Webソケットに複数のスレッドを使用すると問題が生じることがあります。

これはあなたの問題である場合、それに対抗するための最良の方法はそうのようにそれを同期させることです。

Buffer recentWebSocketMessages = BufferUtils.synchronizedBuffer(new CircularFifoBuffer(1000));

代わりに、あなたは、現時点ではそれを行う方法の:

Buffer<String> recentWebSocketMessages = new CircularFifoBuffer<String>(1000);


コピーフォームAPI: https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.2/org/apache/commons/collections/buffer/CircularFifoBuffer.html

+0

優れています。私のアプリが間違いなくマルチスレッド化されていることを考えると、これは根本的な原因ではないでしょう。私はこれを考慮しなかったと信じられない。この徹底的な答えをありがとう。 –

関連する問題