Java.nio loading CPU
I am writing a server app to be able to handle multiple connections (in excess of 100) and I found the Java.nio package to be very useful in doing this.
However I have a problem. When there is at least one connection made to the server, the server's CPU becomes heavily loaded due to thewhile loop in which Selector.select() gets called. The problem is that select() returns a set of keys even if not a single byte was received by any of the SocketChannels registered to to the Selector. So mywhile loop just carries on running many times a second irrespective of whether any of the SocketChannels have received data or not, which they won't in normal operation due to the asynchronous nature of my app (it sends and receives data over cellular phone networks)
The relevant code is below:
this.selector.select();
while (this.opened)
{
Set<SelectionKey> selectedKeys = this.selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator();
while (it.hasNext())
{
SelectionKey key = it.next();
if (key.isAcceptable())
{
//handle a socket accept
}
if (key.isReadable())
{
//handle a socket read
}
if (key.isWritable())
{
//handle a socket write
}
it.remove();
}
this.selector.select();
}
this.selector is just theSelector which belongs to the class in which this code was implemented andthis.opened is just a boolean that will eventually be changed to false by another thread to indicate that the server has shutdown.
Before reading further: please note that this code works and the server handles client requests properly. The issue, is that the CPU is being used inefficiently andnot that the code doesn't work.
The problem is thatthis.selector.select() returns keys whoseready sets indicate that the keys are readable even if their associated SocketChannels have read zero bytes. So this loop just gets called repeatedly which is pointless for 99% of the time due to the infrequency of messages being passed between the client and server (remember: slow cellular phone networks). This also loads the CPU of the server heavily even if there is only 1 socket connection from a client.
So what can be done to prevent this? Is there a way of making theselect() method block until actual data has been read by a SocketChannel?

