大家都说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]
性能提高的就是不需要在读取请求信息和写信息回客户端的时候,也需要线程分发处理,而可以采取主线程中顺序处理即可(因为不需要担心阻塞)?
衷心希望有这方面的高手能解答心中疑惑,万分感谢!
我的想法:
通过你画的图我认为你对NIO的理解基本上还是对的,但是NIO的出现并不是为了提高效率,而是为了节约线程,提高线程的利用率。
“好比有1000个用户进行请求,阻塞IO是开1000个线程进行相应处理,而NIO一样也必须开1000个线程处理;”这句话有问题,1000个用户进行请求,你可以使用一个或者二个线程专门用来实现请求及响应的处理,同时开通一个拥有400个线程的线程池进行业务逻辑处理。这样就可以使用402个线程同时相应这1000个请求,从而实现了线程的利用率。
在阻塞模式下,400个线程只能处理400个请求,其他请求接入的时候会被拒绝。但是在nio模式下,400个线程可以处理1000个请求,看上去就像有1000个线程同时工作。这样就节约了线程。
另外,NIO不会提高效率,相反会降低效率,只不过这种降低是很微小的。
你可以使用tomcat6.0进行一下测试,在bio和nio两种模式下,系统可以支持的连接数差距很大,我做过这方面的压力测试。