`
wangshu3000
  • 浏览: 131375 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

[疑问]关于NIO的耗时服务端业务逻辑问题????

阅读更多
研究了一下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;
					}
				}
			}
		}
	}
}


谁能帮我看看代码问题出现在什么地方??
如果服务端接受请求后启动新的线程作处理,那和传统的多线程阻塞的模式就没有区别了,还是需要消耗线程调度资源。
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics