Я реализую простой файловый сервер с использованием Java NIO с одним потоком выбора и несколькими рабочими потоками (для выполнения реального чтения/записи ).
Основная часть кода выглядит следующим образом:
while (true) {
int num = selector.select();
if (num > 0) {
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
final SelectionKey key = keys.next();
keys.remove();
if (key.isValid()) {
if (key.isAcceptable()) {
accept(key);
} else if (key.isReadable()) {
performReadInWorkerThread (key);
} else if (key.isWritable()) {
performWriteInWorkerThread (key);
}
}
}
}
Как видно из фрагмента кода, когда выбран доступный для чтения/записи канал, я разгружаю чтение/запись из потока выбора в рабочий поток.
Теперь проблема заключается в том, что когда доступный для чтения канал передается рабочему потоку и до того, как он заканчивает/начинает чтение из канала, поток выбора снова зацикливается, и selector.select()
выбирает ранее выбранный доступный для чтения канал (, потому что все еще есть буфер ввода в канале, который еще не полностью использован ранее назначенным рабочим потоком ), поэтому канал снова передается другому рабочему потоку, в результате чего несколько рабочих потоков читают один и тот же канал .
Я считаю, что это проблема дизайна. Мой вопрос в том, как я могу гарантировать, что только один поток читает канал одновременно?