2016-07-15 1 views
-1

Reactor Pattern을 적용한 Java NIO를 사용하는 간단한 서버 클라이언트 애플리케이션을 작성하고 있습니다. 내 이해에 Reactor 클래스는 Events (예 : OP_ACCEPT, OP_READ, OP_WRITE)을 수집해야합니다.리액터 패턴의 개별 스레드에서 이벤트 핸들러 전달

상대적인 EventHandler은 특정 작업을 담당하므로 처리기가 별도의 스레드에서 비동기 적으로 실행되어야한다고 생각합니다. 여기

코드입니다 :

내가이 실행 enter image description here, 그것은 몇 가지 문제를 보여줍니다 계속 실행 while 루프와 Selector은 (1,4,16)의 설정 readyOps을 반환 유지합니다. 나는 AcceptHanndler이 차단 방법으로 OP_ACCEPT을 처리하지 않았기 때문에, 반복자에서 키가 제거되는 이벤트이므로 select() 후에 다시 표시됩니다. 내가 사건을 맡아서는 안되. 달리기를 행선지로?

edge-triggeredlevel-triggered 모델의 개념이 내 마음에 온다 ... 이유는 선택기가 level-triggered 모델에서 실행되기 때문에 이유는 무엇입니까?

+0

Selectors의 요점은 별도의 스레드를 사용해야하는 모자가 아닙니다. – EJP

+0

'Selector'의 요점은 하나의 스레드에서 다중 소켓을 관리하는 것입니다. 클라이언트 당 스레드를 사용하지 않았습니다. – JasonHuang

+0

당신은 그것보다 훨씬 더 잘하고 있습니다. 기본적으로 선택기 이벤트 당 스레드 *를 사용하고 있습니다. 현재 스레드에서 핸들러를 실행하고 데이터베이스 액세스, *를 * 완료 한 후 장기 실행 이벤트에 대한 보조 스레드 만 사용하십시오. 수락 또는 읽기를 완료했거나 이벤트가 현재 스레드에있는 모든 위치에서 완료하십시오. 기본 모델이 깨졌습니다. – EJP

답변

1

예, 선택기가 레벨 트리거됩니다. 사례의 표준 워크 플로는 다음과 같습니다. 채널을 수용 할 수 있음을 감지 한 후 Selector에서 해당 키를 취소하고 해당 키를 이벤트 처리기 스레드로 전달한 후에 만 ​​취소합니다. 이벤트 처리기 스레드가 accept를 완료하고 1) OP_ACCEPT에 대해 서버 소켓을 다시 등록합니다. 2) 구현하려는 프로토콜에 따라 OP_READ 및/또는 OP_WRITE에 대해 허용 된 클라이언트 소켓을 등록합니다. 또는 주 스레드에서 수락을 완료 할 수 있습니다 (성능상의 이유로 연결 클라이언트가있는 경우).

실제로 운영 유형별로 스레드를 차별화하는 것은 확장 성이 없으며 데이터 지역이 좋지 않아 SMP 시스템에서 성능이 떨어질 수 있습니다. 각 클라이언트 소켓을 단일 스레드로 잠그는 것이 좋습니다. 고성능 Java 서버는 대개 수락을 위해 오직 하나의 스레드 (하나의 ServerSocket 만 등록 됨)와 클라이언트 소켓 작업을위한 N 작업자 스레드를 가짐으로써 구현됩니다. 스레드를 수락 루프 작동 : 새로운 클라이언트까지 선택의

  1. 블록 (가)
  2. 가 새로 받아 클라이언트 소켓의 가장 부하가 작업자 스레드 및 전송 소유권

선택 동의를 완료 도착 각 작업 스레드는 자체 Selector와 클라이언트 소켓 집합을 가지며이 소켓 읽기/쓰기를 담당합니다.

+0

답장을 보내 주신 DKS : D. Selector가'level-triggered'이라면, 다음'select()'전에 모든 이벤트 핸들러를 완료해야합니다. 그래서 내가 선택한이 스레드 모델은 절대로 작동하지 않을 것입니다. 실제로 스레드로 모든 '이벤트'를 보유하지 않는다고 생각합니다. 모든 읽기/쓰기 작업에서 AIO를 사용할 수 있기 때문에 스레드를 보유하지 않습니다. 'Selector'는 하나의 스레드를 취해서'event collect'에 집중할 것입니다 ... – JasonHuang