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