I have write a new NIO server
thread, which accept messages from client, but there is some problem. which make it loop too much quickly which make cpu usage to 100%, my run method is follow, any problem?
public void run() {
try {
// This map is used to store clientChannel - Connection pair set,
// store it while accepting a client socket, and retrieve it while reading client request.
final Map channelToConnection = new HashMap();
while (!shouldStop) {
// waiting for events with timeout value
if (selector.select() == 0) {
continue;
}
Iterator it = selector.selectedKeys().iterator();
// process every selectionKey
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
// a client required a connection
if (key.isAcceptable()) {
synchronized (this) {
// reach the max connections limit
if ((this.maxConnections > 0)
&& (this.connectionIdToChannel.size() >= this.maxConnections)) {
continue;
}
}
it.remove();
// get client socket channel
SocketChannel client = server.accept();
// Set Non-Blocking mode for select operation
client.configureBlocking(false);
// recording to the selector (reading)
client.register(selector, SelectionKey.OP_READ);
Connection connection =
new Connection(generator.getNextUUID().toString(), this, client.socket());
synchronized (this) {
connectionIdToChannel.put(connection.getId(), client);
}
channelToConnection.put(client, connection);
// Notify all handlers to process this connection
for (Iterator connIter = this.handlers.values().iterator(); connIter.hasNext()
{
((Handler) connIter.next()).onConnect(connection);
}
} else if (key.isReadable()) {
// if isReadable = true then the server is ready to read
it.remove();
final SocketChannel client = (SocketChannel) key.channel();
try {
Message request = null;
while ((request = IOHelper.readMessage(client, messageFactory)) != null) {
Handler handler = getHandler(request.getHandlerId());
// If no handler register for the given request, simply ignore the request.
if (handler != null) {
// Handler exists for the request.
handler.handleRequest((Connection) channelToConnection.get(client), request);
}
}
} catch (IOException e) {
this.setLastException(e);
// Failed to read from client, so close the corresponding connection
Connection con = (Connection) channelToConnection.remove(client);
this.closeConnection(con.getId());
}
}
}
}
} catch (ProcessingException e) {
this.setLastException(e);
} catch (IOException e) {
this.setLastException(e);
} finally {
synchronized (this) {
this.started = false;
this.shouldStop = false;
// close everything
try {
this.selector.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
this.server.close();
} catch (IOException e) {
e.printStackTrace();
}
this.selector = null;
this.server = null;
this.connectionIdToChannel.clear();
}
}
}