最小限のJMSプロバイダーがあり、UDPを介してトピックメッセージを送信し、TCPを介してメッセージをキューに入れます。単一のセレクターを使用して、UDPおよびTCP選択キーを処理します(SocketChannelsとDatagramChannelsの両方を登録します)。
私の問題は、UDPパケットを送受信するだけですべてがうまくいくが、TCPソケットへの書き込みを開始するとすぐに(Selector.wakeup()を使用してセレクターに実際の書き込みを行わせる)、セレクターが無限ループに入るということです。ループし、空の選択キーセットを返し、100%のCPUを消費します。
メインループのコード(やや簡略化)は次のとおりです。
public void run() {
while (!isInterrupted()) {
try {
selector.select();
} catch (final IOException ex) {
break;
}
final Iterator<SelectionKey> selKeys = selector.selectedKeys().iterator();
while (selKeys.hasNext()) {
final SelectionKey key = selKeys.next();
selKeys.remove();
if (key.isValid()) {
if (key.isReadable()) {
this.read(key);
}
if (key.isConnectable()) {
this.connect(key);
}
if (key.isAcceptable()) {
this.accept(key);
}
if (key.isWritable()) {
this.write(key);
key.cancel();
}
}
}
synchronized(waitingToWrite) {
for (final SelectableChannel channel: waitingToWrite) {
try {
channel.register(selector, SelectionKey.OP_WRITE);
} catch (ClosedChannelException ex) {
// TODO: reopen
}
}
waitingToWrite.clear();
}
}
}
また、UDP送信の場合(TCP送信も同様です):
public void udpSend(final String xmlString) throws IOException {
synchronized(outbox) {
outbox.add(xmlString);
}
synchronized(waitingToWrite) {
waitingToWrite.add(dataOutChannel);
}
selector.wakeup();
}
それで、ここで何が問題になっていますか?UDPパケットとTCPパケットを処理するために2つの異なるセレクターを使用する必要がありますか?