阻塞与非阻塞设计方式的对比。

  一、标准socket

     对socket编程毫无经验的新手(比如我),一开始便看NIO,虽然API是看懂了,却始终无法明白体会和标准socket编程在设计方式上的本质区别。

    可以先看下如下这篇文章,把传统socket编程的服务端基础讲得比较清楚。

     http://blog.csdn.net/lin49940/article/details/4398364

    标准socket的服务端设计,是通过一个阻塞的监听线程和N个工作线程组成。因为每一个SOCKET连接中的操作比如read等,都是阻塞的,因此如果采用单线程处理的话,会出现如下情况:

     A比B请求先到达服务端,因此线程阻塞并等待A的数据。此时B已经准备好数据但迟迟得不到处理。

    而采用多工作线程的时,可能会有N个服务器线程白白将CPU的分片时间浪费在阻塞的等待中。

   

    二、nio

     再来科普下java nio的基础,如下(记得读完一二三四全部文章):

  http://blog.csdn.net/wuxianglong/article/details/6604817

   在nio下,服务器端线程的设计方式通常如下:

    1.创建一个监听线程,新建ServerSocketChannel,调用阻塞的accept()方法监听新的客户端连接。

    2.创建一个唯一的工作线程。当accept()到一个新的客户端连接SocketChannel后,调用工作线程,将该

SocketChannel注册进该工作线程的Selector中。

   3.工作线程中,通过Selector.select(),等待准备好数据通讯的连接。此时上例中的A链接即使比B连接先行到达,但若B预先成为可读状态(比如A是大文件传输),则B必然会被先处理。

 

    网上的DEMO中,通常会把1和2中的监听线程和工作线程合二为一,即将ServerSocketChannel也注册到和工作线程相同的Selector中。但我倾向于两者分开,职责分明。而且利于扩展。

 

     三、对比

         看到这里,最明显的区别,就在于nio可以降低不必要的线程开销。所谓不必要的线程开销,就是那些在标准io下进行阻塞等待的操作。 线程过多,会增加CPU分时的无意义开销。

         但是,nio下是否一定只有一个工作线程呢?其实没那么极端。(二)中的工作线程,可以弱化为一个分发线程,当获取到已经做好准备读或写准备的线程时,可以创建一个线程池来进行真正的处理。但无论如何,浪费在阻塞上的无意义的线程开销没有了。

       

   四、客户端

         前文说的都是服务端,其实客户端也是一个道理。

        标准io下,客户端的多个连接请求必须要用多个线程。

        而nio下,可以用单线程进行处理。

 

   下一步,打算去了解下xsocket和netty这种nio的封装框架,同时找几个使用nio的开源实例进行深入了解(比如redis的客户端JEDIS)

 

   以上是一个socket编程纯新手的理解,希望带给那些有些迷茫的初学者一点点帮助。如有不正确的地方,请务必纠正,也算是对我这个新手的帮助 ^_^

 

          

   

    

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值