У меня есть минимальный поставщик JMS, который отправляет сообщения темы через UDP и сообщения о очереди через TCP. Я использую один селектор для обработки ключей выбора UDP и TCP (регистрации как SocketChannels, так и DatagramChannels).Selector.select() запускает бесконечный цикл
Моя проблема: если я только отправляю и получаю UDP-пакеты, все идет хорошо, но как только я начинаю писать в сокет TCP (используя Selector.wakeup(), чтобы селектор выполнял собственно запись), селектор вводит бесконечный цикл, возвращая пустой набор ключей выбора и потребляя 100% процессор.
Код основного цикла (несколько упрощенно) является:
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();
}
Итак, что здесь не так? Должен ли я использовать 2 разных селектора для обработки пакетов UDP и TCP?
Я нашел кого-то, у кого есть аналогичная проблема: http://web.archiveorange.com/archive/v/xyOAds3Uh2NVesezD5VH. Но решения пока нет ... –