Java nio Selector wakeup

Просьба указать/предоставить мне рабочий пример метода selector.******(); между двумя потоками.

Я попытался создать простую программу, в которой поток ожидает метод selector.select(). Второй поток создает некоторые сокеты и пытается зарегистрироваться с помощью селектора; на котором заблокирован первый поток.

Следовательно, мне нужно использовать метод select ******, но каким-то образом первый поток isnt не выходит из режима блокировки.

В javadoc метода пробуждения указано:

Если другой поток заблокирован в вызове Selector.select() или Selector.select(long), тогда этот призыв вернется немедленно.

P.S Существует несколько других способов работы; один из них - select (timeout), но я пытаюсь выяснить, где ошибка.

Псевдо-код:

ПЕРВАЯ РЕЗЬБА:

static Selector selector = Selector.open();
while(true) {
 int n = selectorGlobal.select();
 selectorKeySet = selectorGlobal.selectedKeys().iterator();
 while (selectorKeySet.hasNext()) {
 selectionKey = selectorKeySet.next();
 if (selectionKey.isReadable()) {
 //do something
 }
 if(selectionKey.isAcceptable()) {
 //accept
 }
 }
}

ВТОРАЯ РЕЗЬБА:

while (itr.hasNext()) { 
 data = (String) itr.next();
 String IP = data.get(0);
 String Port = data.get(1);
 SocketChannel socketChannel = SocketChannel.open();
 socketChannel.configureBlocking(true);
 boolean isConnected = socketChannel.connect(new InetSocketAddress(IP, Port));
 ClassName.selector.******();
 SelectionKey selectionKey = SelectSockets.registerChannel(ClassName.selector,
 socketChannel, SelectionKey.OP_READ);
}
1 ответ

Вероятно, вы не хотите, чтобы сокет из Thread 2 блокировался, если вы регистрируете его в селекторе (поскольку селекторы предназначены для неблокирующего ввода-вывода). Я думаю, что также распространенная практика позволяет селектору обрабатывать соединение с OP_CONNECT (используя SocketChannel.finishConnection()).

Похоже, у вас может быть потенциальное состояние гонки здесь. Представьте себе эту серию событий:

  • Тема 1: selector.select()
  • ... время проходит...
  • Тема 2: Thread1.selector.******()
  • Тема 1: проверяет ключи на приемлемость.
  • Тема 1: проверяет ключи на доступность
  • Тема 1: цикл
  • Тема 1: selector.select()
  • Тема 2: попробуйте зарегистрироваться в селекторе (но слишком поздно для этого select())

Я предлагаю, чтобы Thread 2 установил SocketChannel, запихните его куда-нибудь, когда Thread 1 может получить его (убедитесь, что это потокобезопасно, когда вы это сделаете), затем просыпайте селектор, дайте ему проверить существующие ключи в Thread 1, и Thread 1 зарегистрирует новый SocketChannel, прежде чем снова вызовет Selector.select().

licensed under cc by-sa 3.0 with attribution.