- Селектор может использоваться для мониторинга выбираемых каналов Java nio, когда канал готов к событию, которые можно прочитать, записать, принять, подключать (согласно зарегистрированному интересу), селектор сообщит нам. Получите готовое событие, используя API Register. /> ‘Selecter’ поддерживает три набора ключей. Набор ключей отбора, которые сняты из селектора.
b. Отменен набор ключей не является безопасным потоком. < /Li>
Зарегистрированный набор ключей:
a. Набор ключей выбора, которые зарегистрировались в селекторе.
b. Зарегистрированный набор клавиш безопасен. Набор ключей отбора, которые имеют хотя бы одну заинтересованную операцию в состоянии готового.
b. Выбранный набор ключей не является безопасным потоком. < /Li>
< /ul>
Мы блокируем наш поток (network_io_in) на вызове Selecter Arteafct Select (), который будет разблокировать, когда хотя бы один из зарегистрированных каналов готов выполнять заинтересованные операции. /> < /ol>
Сначала он итерации из -за отмененного набора ключей и освобождает ресурсы W.R.T Channel /Socket, которые сняты из селектора. SET. < /li>
Примечание. Все эти шаги внутренне синхронизируются на селекторе, затем на наборе отмены и выбранного ключа. Выбранный набор ключей
, который является частным элементом селектора.
Мы изнашиваемся над выбранным набором клавиш, определите, какая заинтересованная операция готова (чтение/запись/connect/accept) и выполняем, что io. мы. /> Наблюдение: < /li>
< /ol>
Все потоки заблокированы на вызове и вышли один за другим. /> Рассмотрение другого потока T2, которое заблокировано на вызове SELECT и выполняется на шаге, упоминается в 7.C, также работает на одном и том же выбранном наборе клавиш. {< /p>
Код: Выделить всё
while (true) {
println ("Thread " + Thread.currentThread().id + "blocked on select")
// Threads will get blocked on the select calls until there is at least one channel /socket which is ready.
selector.select ()
println ("Thread " + Thread.currentThread().id + "comes out of select")
// Returns the reference of the selected key set.
val selected_key_set = selector.selectedKeys()
val iterator = selected_key_set.iterator()
println ("Thread " + Thread.currentThread().id + “operating on the selected key set”)
while (iterator.hasNext()) {
// Extract the key (selection key object ) and increment the iterator.
val key = iterator.next()
// Remove the Seleciton Key object from the selected key set.
iterator.remove()
println (" Event receive corrsponding to descriptor id " + key.attachment() as Int)
when {
// Channel/Socket is ready for Receive.
key.isReadable -> {
…
// Buffer in which to copy the receive data.
var buffer = ByteBuffer.allocate(1024)
// Get the channel from Selection key object and call the receive.
(key.channel() as DatagramChannel).receive(buffer)
…
// Print the Receive data .
println ("Message Received: ${String(receivedData)}")
}
key.isWritable -> println("Write Ready")
}
}
}
< /code>
} < /p>
< /li>
< /ul>
Теперь добавление потока кода, где мы сделали синхронизацию нами. Какой канал/сокет прослушивается и зарегистрирован в селекторе. /> Поток, который выходит из вызова вызова вызова, скажем, T1 получает блокировку на selected_key_set, чья ссылка возвращается Selectedkeys () Call. () Вызов. while (true) {
println ("Thread " + Thread.currentThread().id + "blocked on select")
selector.select ()
println ("Thread " + Thread.currentThread().id + "comes out of select")
val selected_key_set = selector.selectedKeys()
// Here we have synchronize on the selected_key_set which ensures that thread which are blocked on the select call will not be able to use it if another thread is already operating over it.
synchronized (selected_key_set) {
println ("Thread " + Thread.currentThread().id + "blocked on selected key set")
val iterator = selected_key_set.iterator()
while (iterator.hasNext()) {
val key = iterator.next()
println (" Event receive corrsponding to descriptor id " + key.attachment() as Int)
iterator.remove()
when {
key.isReadable -> {
counter++;
var buffer = ByteBuffer.allocate(1024)
(key.channel() as DatagramChannel).receive(buffer)
buffer.flip()
val receivedData = ByteArray(buffer.remaining())
buffer.get(receivedData)
println ("Recv Event Number: "+ counter)
println ("Message Received: ${String(receivedData)}")
}
key.isWritable -> println("Write Ready")
}
}
}
println ("Thread " + Thread.currentThread().id + "comes out of selected key set")
}
Здесь мы делаем синхронизацию на выбранном наборе ключей, когда мы выполняем обработку готовых событий (чтение/запись/принять/подключить), что позволяет только одному потоку работать за раз и блокирует другие потоки. обработка за раз, а другой будет ждать.
Подробнее здесь: https://stackoverflow.com/questions/790 ... s-on-selec