大家都说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是 
 而NIO就是  性能提高的就是不需要在读取请求信息和写信息回客户端的时候,也需要线程分发处理,而可以采取主线程中顺序处理即可(因为不需要担心阻塞)? 衷心希望有这方面的高手能解答心中疑惑,万分感谢!          

解决方案 »

  1.   

    好比有1000个用户进行请求,阻塞IO是开1000个线程进行相应处理,而NIO一样也必须开1000个线程处理
    好像 NIO 不需要开1000个线程处理吧,看下面的达人解释
      

  2.   

    NIO感觉都是用在服务器端吧,比如之前HTTP服务器要用一个MAIN Thread接受请求,然后转发给其它的线程,但用NIO的话,一个MAIN thread就可以用轮询的方法处理多个请求,因为新建一个thread,要分配的默认栈空间大小是512KB,所以如果请求多的话,也能省很多空间吧。至于速度,chanel + buffer和BufferInput/OutputStream + byte[], 读写速度是没啥差别的。我比较好奇,NIO是怎么实现无阻塞IO的,理论上说IO肯定要阻塞的啊,楼下继续
      

  3.   

    我个人认为传统BIO我们一般在接受到客户端的connection的时候,为了接受客户端信号,我们必须开启新的线程进行R/W,这个时候客户端即使connect服务器成功,但并不表示其一定会马上对服务器进行w,因此这个时候,就造成了服务器的read阻塞,而使用了NIO以后,这种情况不会出现,即使双方连接建立,只有当客户端真正write数据的时候,服务器才会启动线程去read,所以使得在处理过程中,线程的使用周期缩短以至于可以在很短的时间内程序将线程返还给线程池,加大了系统的吞吐量。