iteye_19447 2010-04-06 15:53
浏览 219
已采纳

关于JAVA NIO的一点疑惑

大家都说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]

性能提高的就是不需要在读取请求信息和写信息回客户端的时候,也需要线程分发处理,而可以采取主线程中顺序处理即可(因为不需要担心阻塞)?

衷心希望有这方面的高手能解答心中疑惑,万分感谢!

  • 写回答

2条回答 默认 最新

  • lvhuiqing 2010-04-06 16:31
    关注

    我的想法:
    通过你画的图我认为你对NIO的理解基本上还是对的,但是NIO的出现并不是为了提高效率,而是为了节约线程,提高线程的利用率。
    “好比有1000个用户进行请求,阻塞IO是开1000个线程进行相应处理,而NIO一样也必须开1000个线程处理;”这句话有问题,1000个用户进行请求,你可以使用一个或者二个线程专门用来实现请求及响应的处理,同时开通一个拥有400个线程的线程池进行业务逻辑处理。这样就可以使用402个线程同时相应这1000个请求,从而实现了线程的利用率。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 YOLO检测微调结果p为1
  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题