ExecutorService를의 집행 사이에 동기화하는 방법

이삭 베로 :

나는 보통 크기의 약 2000 이러한 클라이언트들이 왕래, 동적, 클라이언트 소켓의 목록을 가지고있다.

나는이 ExecutorService이러한 스레드를 처리하는 32 개 스레드의 고정 스레드 풀을. 이 executor 서비스를 디코딩하고이 2000 클라이언트로 전송되는 메시지를 보내는 책임이 있습니다.

나는 실행 프로그램 서비스의 두 개 이상의 스레드가 동시에 같은 클라이언트를 처리하는 것을 방지합니다.

한 가지 방법은 다른 소개 할 수 부기 스레드 (I 32 개 + 1 스레드로 끝날 수 있도록)를 호출 할 책임이있는 ExecutorService.submit(mesage)같은 클라이언트에 해당하는 이전 메시지가 완료되면. 그러나 나는 확실하지는이 새로 도입 된 것을 의미 병목 현상을 소개합니다 경우입니다 부기 스레드가 메시지를 제출 유지할 수 없습니다.

이상적으로, 나는 메시지 부하가 ​​균등하게 클라이언트 사이에 분산되지 않기 때문에, 사전에 고객의 세트에 스레드를 미리 할당하고 싶지 않아요. 또한 사전에 알려져 있지 않다.

이를위한 방법은 무엇입니까? 그들에 의해 제공되는 java.util.concurrent기능?

최신 정보

의견이 일부 오해가 있다고 지적이 빠른 요약 한 것입니다 :

  • 나는 2000 스레드로 끝날 것처럼 나는 클라이언트 당 하나의 스레드를 원하지 않는다.

  • 이상적으로, 나는 메시지 속도가 균일하게 사전에 알려진 모든 고객과하지 사이에 분산되지 않기 때문에, 고객의 세트에 스레드를 미리 할당하고 싶지 않아요.

  • 메시지 순서를 유지해야합니다.

  • 나는 스레드가 좋지 않을 것이라고 생각 A스레드를 기다리고 B있기 때문에 B이미 같은 클라이언트에 메시지를 보내고있다. 즉, 항상 하나의 스레드가 하나의 클라이언트를 처리 중입니다.

안드레아스 :

쓰레드 (A)의 메시지 (# 1) 처리를 시작하면, 그것은 공유 관리자 오브젝트와 클라이언트 ID를 등록 할 필요가있다. 각 등록 된 클라이언트의 경우, 큐가있다.

다른 스레드 (B)는 동일한 클라이언트에 대한 메시지 (# 2)의 처리를 개시 할 때, 상기 등록은 스레드 A가 이미 처리하고 검색하며, 클라이언트의 큐에 메시지 # 2를 추가 할 것이다. 스레드 B는 중지하고 다음 메시지를 처리합니다.

스레드 A가 메시지 # 1으로 수행되면 등록을 취소하려고하지만, 메시지 # 2 큐이기 때문에, 스레드 A 대신에 그 메시지를 처리하기 시작합니다. 다시 등록을 취소하려고 할 때 그 후, 거기에는 대기중인 메시지가 없습니다 및 스레드 중지하고 다음 메시지를 처리합니다.

두 번째 메시지 중 하나 길을 잃지 않고, 스레드 B에 의해 처리 또는 스레드에 넘겨되도록이 제대로 동기화 액세스 관리자 코드까지입니다.

스레드 B가 스레드 A, 즉 유휴 시간을 기다릴 것이며, 그 메시지 # 2가 동시에 같은 클라이언트에 대한 두 개의 메시지를 처리하지 않고, 즉시 최소 지연 즉, 가능한만큼 처리되도록 상기 논리 보장한다.

메시지 위해서는 각 클라이언트는 유지됩니다. 메시지 번호 (2)의 처리가 지연되기 때문에 세계적 메시지 순서는 물론 유지되지이다.

참고, 모든 큐는 일반적으로 비어있게됩니다 때문에 메시지 큐하다 "중복"단지 거기 각 스레드에 대해 하나의 큐, 그래서 32 대기열이 될 것이다.


최신 정보

예 : 여기에 식별을 위해, 메시지의 이름을 지정하는 clientId.messageId경우 messageId글로벌입니다.

메시지는이 순서대로 집행 인 (3 실)에 제출 :

1.1, 2.2, 1.3, 2.4, 3.5, 1.6

  1. A는 집어 스레드 1.1처리를 시작합니다.

  2. 스레드 B는 픽업 2.2처리 시작한다.

  3. 스레드 C는 집어 들고 1.3, 다음, 반환 A의 큐 스레드에 추가합니다.

  4. 스레드 C는 집어 들고 2.4, 다음, 반환 B의 큐 스레드에 추가합니다.

  5. C는 픽업 스레드 3.5처리를 시작한다.

  6. 스레드 A는 메시지와 함께 수행 1.1하고 시작을 처리 1.3.

  7. 스레드 C는 메시지와 함께 수행 3.5하고 돌아갑니다.

  8. 스레드 C는 집어 들고 1.6, 다음, 반환 A의 큐 스레드에 추가합니다.
    스레드 C는 현재 유휴 상태입니다.

  9. 스레드 B가 메시지를 완료 2.2하고 처리가 시작 2.4.

  10. 스레드 A는 메시지와 함께 수행 1.3하고 시작을 처리 1.6.

  11. 스레드 B는 메시지와 함께 수행 2.4하고 돌아갑니다.
    스레드 B는 현재 유휴 상태입니다.

  12. 스레드 A는 메시지와 함께 수행 1.6하고 돌아갑니다.
    스레드 A가 유휴 상태입니다.

추천

출처http://43.154.161.224:23101/article/api/json?id=195741&siteId=1