NIO Best Practices - Выбираемый канал и Проценты интереса - PullRequest
5 голосов
/ 21 мая 2010

используя java.nio, нужно регистрировать интерес к операциям через SelectableChannel:

SelectionKey = SelectableChannel.register(selector, interestInOpsBitmask)

Регистрация процентов:

  • перезаписывает существующий ключ SelectionKey, выполняя SelectableChannel.register с новым Ops
  • VS. обновление существующего SelectionKey с помощью key.interestOps (key.interestOps () | newOp)

Незарегистрированный интерес:

  • SelectionKey.cancel и SelectableChannel.register с новыми Ops
  • VS. обновление существующего SelectionKey, как указано выше

Есть ли плюсы и минусы?

Спасибо

Ответы [ 2 ]

3 голосов
/ 15 июля 2010

Если вы всегда отправляете выполнение в пул потоков после возврата из select (), вы можете немедленно отменить ключ, поскольку вы теряете контроль в течение времени выполнения Runnable.

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

Даже если вы отмените ключ, поток может зарегистрировать тот же канал (обновить ключи выбора) до того, как канал станет незарегистрированным (из-за вашего предыдущего key.cancel()). Что опять, вызовет CancelledKeyException .

Чтобы избавиться от этой ловушки, вы можете обрабатывать события всегда в следующем цикле:

while (true) { // true or something less risky
    //for each pendingTasks call
    pool.execute(task);
    Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
    while (iter.hasNext()) {
        SelectionKey key = iter.next();
        iter.remove();
        key.cancel();
        //store dispatch for the next while iteration
        pendingTasks.add(task); // do not execute tasks before next select()
    }
    selector.select(TIMEOUT); // or selectNow if there are 
                              //any pending events to handle.
}

Выполнение Firt почти никогда не вернет ключи, но метод select () в конце вашего цикла МОЖЕТ гарантировать, что канал отмененного ключа будет незарегистрированным (не забывайте, что это ваше значение) от селектора.

Однако, если вы просто выполняете задачу в том же потоке, вы слушаете события селектора, обновляя звуки легче и безопаснее.

3 голосов
/ 21 мая 2010

Я бы обновил существующие проценты с использованием оператора or, как вы предлагаете. Я был бы обеспокоен отсутствием выбора, если бы я (временно) отменил клавишу выбора.

Кроме того, отмена + перерегистрация кажется более сложной, чем обновление.

Если у вас нет логической причины для регистрации в новых операциях, я бы предложил всегда обновляться.

...