2016-10-31 11 views
2

배경

내가 최근 메시지의 컬렉션은 웹 소켓 연결을 통해 수신 들어있는 아파치 코 몬즈 라이브러리에서 CircularFifoBuffer 클래스를 사용하려고 시도하고있다. 그러나 리눅스 배포에서 CircularFifoBuffer의 크기 제한에 도달하면 BufferOverflowException이 발생합니다.아파치 코 몬즈 - CircularFifoBuffer BufferOverflowException을

나는 아직도 자바 상당히 새로운 오전 그러나 여기에서 나는 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에서) 내가 해결 할 수있는에가 발생하지 않습니다 정적 변수를 이와 같이 정의함으로써? (이 단단히 커플 BoundedFifoBufferCircularFifoBuffer 구현 recentWebSocketMessages에도 불구하고)

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

편집

이 감사는이 구현은 동기화되지 단순한 사실을 지적하기위한 sorifiend 톰.

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

: 관심이있는 경우,이 간단한 나사 아래 예는 멀티 스레딩 /을 BufferOverflowException는 (버퍼 내 원래 정의에) 발생 발생할 수있는 동시에, 버퍼 액세스 문제 복수 스레드임을 증명

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

[* "이 구현은 동기화되지 않습니다."* (https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.2/org/apache/commons/collections/buffer) /CircularFifoBuffer.html) ... 여기에 문제가있을 수 있습니다. – Tom

답변

2

빠른 답변 : 아니, 그런 식으로 변경하는 것은 늘 정말 도움이 recentWebSocketMessages의 다음과 같은 정의와 같은 코드는 API와 sorifiend의 대답에 언급 된 버퍼에 대한 액세스가 동기화되기 때문에이 BufferOverflowException throw하지 않습니다. 항목이 자동으로 공간을 추가 제거해야하기 때문에

테스팅 메시지는 문제의 원인이 실 거예요 :

CircularFifoBuffer 전체 경우의 가장 오래된 요소를 대체하는 고정 된 크기 와 밖으로 첫 번째 버퍼에 처음이다.

CircularFifoBuffer 제거 순서는 삽입 순서를 기반으로합니다. 요소는 이 추가 된 순서와 동일한 순서로 제거됩니다. 반복 순서는 제거 순서와 동일합니다.

그러나 버퍼 제한 (1000 경우 귀하의 경우) 때 웹 소켓에 대해 여러 스레드를 사용할 때 때로는 문제가 있다고 생각합니다. 이 문제는 그렇게처럼 동기화하는 것입니다 방지하는 가장 좋은 방법은 다음의 경우

:

당신이 순간에 그것을 할 방법 대신 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

우수. 내 응용 프로그램이 확실히 멀티 스레드라고 생각하면 근본 원인보다 더 많은 가능성이 있습니다. 나는 이것을 고려하지 않았다는 것을 믿을 수 없다. 이 철저한 대답에 감사드립니다. –