JAVA NIO provides an API to write a TCP server using NIO architecture, as follows.
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.ParseException;
import java.util.*;
public class NIOServer implements Runnable{
private InetAddress addr;
private int port;
private Selector selector;
public NIOServer(InetAddress addr, int port) throws IOException {
this.addr = addr;
this.port = port;
}
public void run(){
try {
startServer();
}catch(IOException ex){
System.out.println(ex.getMessage());
}
}
private void startServer() throws IOException {
this.selector = Selector.open();
ServerSocketChannel serverChannel = serverSocketChannel.open();
serverChannel.configureBlocking(false);
InetSocketAddress listenAddr = new InetSocketAddress(this.addr, this.port);
serverChannel.socket().bind(listenAddr);
serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
while (true) {
this.selector.select();
Iterator keys = this.selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = (SelectionKey) keys.next();
keys.remove();
if (! key.isValid()) {
continue;
}
if (key.isAcceptable()) {
this.accept(key);
}
else if (key.isReadable()) {
this.read(key);
}
else if (key.isWritable()) {
this.write(key);
}
}
}
}
}
This uses a single thread that will process events such as read, write and accept.
Compared to Blocking thread per connection architecture this is much preferred because of its non-blocking nature that causes minimum cache misses, thread overheads, low cpu migrations.
However, this architecture uses only a single thread. In a multi-process environment (for example 4 core cpu), NIO architecture wastes other cores. Is there a design approach I can use to utilize all the cores with NIO architecture?
NIO2 (which is based on proactor pattern) is one such option. But the underlying architecture is very different to original NIO.