大家都说NIO在传统阻塞IO的基础上面,提高了效率,增大了服务器并发处理能力,我对此有一点点疑惑;
传统型的IO,处理过程如下
(1)服务器准备就绪---->(2)接受连接(accept阻塞)------>(3)读取服务器请求(阻塞)------>(4)改请求业务逻辑处理(如数据库)----->(5)发送响应至服务器----------(2)重新开始
如果在(2)accept的时候,接受到A请求,服务器会read A请求的请求数据,如果在此时A数据读取阻塞,那么接下来的B请求,将得不到响应;
为此。我们通常的处理方式是在
|--------------线程1
(2)接受连接(accept阻塞)---|--------------线程2
|--------------线程3
........
进行线程分发;
在使用了NIO以后,利用一种selector.select同样是的需要阻塞才能得到,这一点我认为跟accept没有本质区别,不同的是select能够得到多个channel的处理状态,迭代进行顺序处理:
for (;;) {
try {
selector.select();
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();
if (key.isAcceptable()) {
handleAccept(key);
} else if (key.isReadable()) {
handleRead(key);
} else if (key.isWritable()) {
handleWrite(key);
} else if (key.isConnectable()) {
handleConnect(key);
}
if(!key.isValid()){
key.cancel();
}
it.remove();
}
} catch (IOException e) {
continue;
}
}
处理方法如下:
public void handleAccept(SelectionKey key) {
}
public void handleRead(SelectionKey key) {
}
public void handleWrite(SelectionKey key) {
}
对于一些数据库操作,每次在处理handleRead的时候,我们还是必须的使用多线程对请求进行处理,比如查询数据库等等耗时操作,(别拿那张helloworld回显的例子做比喻)我一直在疑惑,好比有1000个用户进行请求,阻塞IO是开1000个线程进行相应处理,而NIO一样也必须开1000个线程处理;而假如我把一次请求处理周期看成三段:
--------------------|------------------------|------------------
读取请求信息 业务处理(数据库访问) 写信息回客户端
阻塞IO是
[img]http://dl.iteye.com/upload/attachment/230022/116b63b5-b54f-340b-a250-154b24badc41.bmp[/img]
而NIO就是
[img]http://dl.iteye.com/upload/attachment/230020/3d8da6d3-44fc-3ff0-8520-1a831f9db789.bmp[/img]
性能提高的就是不需要在读取请求信息和写信息回客户端的时候,也需要线程分发处理,而可以采取主线程中顺序处理即可(因为不需要担心阻塞)?
衷心希望有这方面的高手能解答心中疑惑,万分感谢!