2010-03-09 3 views
6

각 스레드마다 고유 한 동시 대기열이있는 스레드가 여러 개 있으며 모든 스레드는 메시지를 검색하는 무한 루프를 실행합니다. 대기열 중 하나가 일정 기간 (몇 초 정도) 메시지를 수신하지 못하고 큰 버스트가 발생하여 처리 속도가 빨라질 수 있습니다.자바 동시성 - 차단해야합니까?

첫 번째 경우에 가장 적합한 것이 무엇인지 알고 싶습니다. 블로킹 큐를 사용하고 더 많은 입력이 있거나 Thread.yield()를 수행 할 때까지 스레드를 차단 하시겠습니까?

동시 스레드 수가 시간에 따라 증가 할 수 있기 때문에 주어진 시간에 가능한 한 많은 CPU 리소스를 사용하고 싶지만 메시지 처리가 뒤처지는 것을 원치 않습니다. 보장이 없습니다. 스레드가 yield()를 수행 할 때 실행을 위해 다시 스케줄 될 시점. 하드웨어, 운영체제 및 기타 요인들이 여기서 중요한 역할을한다는 것을 알고 있지만 Java (JVM) 관점에서 살펴보면 가장 최적의 것은 무엇입니까?

답변

9

항상 대기열을 차단하십시오. 자바는 내부적으로 대기열에 들어간다.

다른 말로하면 : 블록하지 않고 그 중 하나에서 양보하면 다른 스레드에서 성능 이점을 얻을 수 없습니다.

+0

아니요, [disruptor] (https://github.com/LMAX-Exchange/disruptor) 라이브러리를 사용해보세요. 수확량에 의해서만 최고의 성능을 얻었습니다! – qinxian

7

확실하게 차단 대기열을 사용하려고합니다.이 작업은 수행 할 작업이 없을 때 스레드가 CPU 시간을 사용하지 않게하려는 목적으로 설계되었습니다.

Thread.yield()는 매우 까다로운 동물입니다. 스케쥴러는 정확히 무엇을하는지에 큰 역할을합니다. 간단하면서도 유효한 구현은 아무 것도하지 않는 것입니다.

0

또는 구현 된 ExecutorService 구현 중 하나 (아마도 ThreadPoolExecutor) 중 하나를 사용하도록 구현을 변환하는 것이 좋습니다.

이 코드는 사용 사례에 적합하지 않을 수도 있지만, 그렇다면 코드에서 스레드 관리에 대한 걱정의 부담을 덜어줍니다. 이러한 항복 또는 간단히 사라지지 않는 문제는 제거됩니다.

또한 더 나은 스레드 관리 알고리즘이 미래에 나타날 경우 (예 : Apple Grand Central Dispatch과 유사) 응용 프로그램을 거의 사용하지 않고 변환 할 수 있습니다.

0

또 다른 작업은 대기열에 대한 동시 해시지도를 사용하는 것입니다. 읽기를 할 때 찾고있는 객체에 대한 참조를 제공하므로 방금 큐에 넣은 메시지를 놓칠 수 있습니다. 그러나이 모든 일이 메시지를 듣는 것이라면 다음 반복을 포착합니다. 메시지가 다른 스레드에 의해 갱신 될 수 있다면 다른 것입니다. 그러나 실제로 내가 볼 수있는 것을 차단할 이유가없는 것 같습니다.