2017-12-21 4 views
1

소켓 채널을 셀렉터에 등록합니다. 해당 소켓 채널 & 셀렉터의 키를 취소하면 해당 키는 영원히 유효하지 않습니다. 그래서 소켓 셀렉터에 셀렉터를 추가하려고하면 CancelledKeyException이 발생합니다. 동일한 셀렉터에 대한 socketChannel에 대한 호출이 예외를 throw합니다.

Selection key = channel.register(selector, ops, this); 
key.cancel(); 
key = channel.register(selector, ops, this); 

자료 문서

나는 내가 또 다른 "선택 키"를 얻을 줄 알았는데하지만 그것은 불가능한 것 같다, 그래서,

If this key has already been cancelled then invoking this method has no 
effect. Once cancelled, a key remains forever invalid. 

을 같은 상태. 각 채널은 등록 할 때 각 선택기에 고유 한 키를 생성하지만 키를 취소하면 채널의 키 세트에서 해당 키를 제거하지 않습니다. 따라서 소켓 채널 & 선택기 쌍을 사용할 수 없습니다.

맞습니까? 이 구현은 의미가 없으므로 뭔가 놓치기를 바랍니다.

답변

0

이것은 이상한 것 중 하나입니다. 내가 찾을 때 발견 할 수없는 문서의 어딘가 깊은 부분은 취소가 다음번에 처리되는 문장 인 것입니다 select(). 따라서 취소 후 및 두 번째 전에 전에 selectNow()에 전화해야합니다.

하지만 개입하지 않고도이 작업을 수행하는 이유는 무엇입니까? select()은 수수께끼입니다. 키를 취소하지 말고 다시 등록하지 마십시오 : interestOps 만 변경하십시오.

+0

로드 균형 조정용입니다. 스레드는 socketchannel을 받아들이고, 첫 번째 메시지를 읽고, 선택기에서 제거하고, 어떤 작업자가 해당 채널을 가져야하는지 결정하고, 대상 작업자에게 채널을 보냅니다. 그래서 dest가 그 자체라면 문제가됩니다. dest == 자체 검사로 처리 할 수 ​​있지만이 SelectionKey가 실제로이 방법으로 작동하는지 알고 싶었습니다. 답변 감사합니다. – vkx

+0

맞습니다. 다른 선택기로 이동하는 경우 취소 만하면됩니다. 따라서 'if (dest! = 자체) {key.cancel(); }'. 동일한 'Selector'인 경우, 후속 'register()'는 실제로 업데이트 된 'interestOps'및 'attachment'가있는 동일한 키를 반환합니다. – EJP

관련 문제