I am implementing a simple file server using Java NIO with one selecting thread and multiple worker threads(for performing real read/write).
The main part of the code looks like the following:
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);
}
}
}
}
As you can see from the code snippet, when a readable/writable channel is selected, I offload the read/write from the selecting thread to a worker thread.
Now the problem is that when a readble channel is handed over to the worker thread, and before it finishes/starts reading from the channel, the selecting thread loops again, and selector.select()
selects the previously selected readable channel(because there's still input buffer in the channel that is not yet fully consumed by the previously assigned worker thread), so again the channel is handed over to another worker thread, resulting in multiple worker threads reading the same channel.
I believe this is a design problem. My question is how I can ensure only one thread reading a channel at the same time?