Я разработал сервер, используя Java nio. И несколько соединений (60-70) установлено. Хотя только соединения установлены и данные не передаются, он потребляет 30% моего процессора (i7 8-го поколения. 12 ядер). В случае передачи данных это составляет 80-90%. Когда я анализирую программу с помощью jvisualvm, кажется, что используется только метод selector.select (). Интересно, что делать, чтобы уменьшить загрузку процессора.
private void startServer() throws IOException {
this.selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
// retrieve server socket and bind to port
listenAddress = new InetSocketAddress("localhost", 8090);
serverChannel.socket().bind(listenAddress);
serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started...");
while (true) {
// wait for events
this.selector.select();
//work on selected keys
Iterator keys = this.selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = (SelectionKey) keys.next();
// this is necessary to prevent the same key from coming up
// again the next time around.
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);
}
else if (key.isConnectable()) {
this.connect(key);
}
}
}
}
private void accept(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
// register channel with selector for further IO
dataMapper.put(channel, new ArrayList());
channel.register(this.selector, SelectionKey.OP_READ);
}
//read from the socket channel
private void read(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int numRead = -1;
numRead = channel.read(buffer);
if (numRead == -1) {
this.dataMapper.remove(channel);
channel.close();
key.cancel();
return;
}
processBuffer(buffer);
}
public void startClient() throws IOException, InterruptedException {
String remoteHost = "localhost";
int remotePort = 8090
SocketChannel client = SocketChannel.open();
client.configureBlocking(false);
client.bind(new InitSocketAddress(0);
client.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
client.connect(new InetSocketAddress(remoteHost, remotePort));
client.register(this.selector, SelectionKey.OP_CONNECT);
}
public void connect(SelectionKey key){
SelectableChannel channel = key.channel();
SocketChannel socketChannel = (SocketChannel) channel;
boolean isConnected = socketChannel.finishConnect();
if(!isConnected)
System.out.println("Not Connectted!");
}
public void write(SelectionKey key){
SocketChannel socketChannel = (SocketChannel) channel;
ByteByffer buffer = getBuffer();
while(buf.remaining()>0){
socketChannel.write(buf)
}
//we wrote the data, now we interested in waiting for data.
key.interestOps(SelectionKey.OP_READ);
}