研究了一下NIO的非阻塞连接。。似乎有点问题。。
当
服务端处理一个比较耗时的业务请求的时候,客户端是阻塞的。。
场景:2个客户端请求,在服务端分辨,第一个处理了10秒钟,在处理过程中,第二个请求进不来。
因为是轮询selector来获取处理的内容的,而两次请求是属于两个selector,第一个selector没有处理完,第二个就一直等待。。。。。。。。。这就有问题,不是并发了。。。
package com.test.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
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.nio.channels.spi.SelectorProvider;
import java.util.Date;
import java.util.Iterator;
public class NIONBServer {
public static int count = 0;
/**
* @param args
* @throws IOException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel server = ServerSocketChannel.open();
Selector acceptSelector = SelectorProvider.provider().openSelector();
server.socket().bind(new InetSocketAddress(8787));
server.configureBlocking(false);
server.register(acceptSelector, SelectionKey.OP_ACCEPT);
for (;;) {
acceptSelector.select();
Iterator<SelectionKey> iter = acceptSelector.selectedKeys().iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
if (key.isAcceptable()) {
ServerSocketChannel serverc = (ServerSocketChannel) key.channel();
SocketChannel channel = serverc.accept();
channel.configureBlocking(false);
// channel.register(acceptSelector, SelectionKey.OP_READ);
channel.register(acceptSelector, SelectionKey.OP_WRITE);
} else if (key.isReadable()) {
if (0 == count++) {
System.out.println("Count=" + count + " Sleep=" + 5000);
Thread.sleep(10000);
}
System.out.println("Count=" + count);
SocketChannel channel = (SocketChannel) key.channel();
channel.register(acceptSelector, SelectionKey.OP_WRITE);
} else if (key.isWritable()) {
if (0 == count++) {
System.out.println("Count=" + count + " Sleep=" + 5000);
Thread.sleep(10000);
}
System.out.println("Count=" + count);
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer block = ByteBuffer.allocate(100);
block = ByteBuffer.wrap(new Date().toString().getBytes());
channel.write(block);
channel.close();
}
}
}
}
}
package com.test.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class NIOClient {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
SocketChannel client = SocketChannel.open();
client.configureBlocking(false);
Selector selector = Selector.open();
client.register(selector, SelectionKey.OP_CONNECT);
InetSocketAddress ip = new InetSocketAddress("localhost", 8787);
client.connect(ip);
ByteBuffer buffer = ByteBuffer.allocate(1024);
FOR: for (;;) {
selector.select();
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
if (key.isConnectable()) {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending())
channel.finishConnect();
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
int count = channel.read(buffer);
System.out.println("count:" + count);
if (count > 0) {
buffer.clear();
System.out.println(new String(buffer.array()).trim());
} else {
client.close();
break FOR;
}
}
}
}
}
}
谁能帮我看看代码问题出现在什么地方??
如果服务端接受请求后启动新的
线程作处理,那和传统的多线程阻塞的模式就没有区别了,还是需要消耗线程调度资源。