|
|
研究了一下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;}}}}}}
谁能帮我看看代码问题出现在什么地方??
如果服务端接受请求后启动新的线程作处理,那和传统的多线程阻塞的模式就没有区别了,还是需要消耗线程调度资源。 |
|