阻塞和非阻塞通信

        阻塞和非阻塞通信


 阻塞通信意味着通信方法在尝试访问套接字或者读写数据时阻塞了对套接字的访问。在 JDK 1.4 之前,绕过 阻塞限制的方法是无限制地使用线程,但这样常常会造成大量的线程开销,对系统的性能和可伸缩性产生影响。java.nio 包改变了这种状况,允许服务器有效地使用 I/O 流,在合理的时间内处理所服务的客户请求。


没有非阻塞通信,这个过程就像我所喜欢说的为所欲为那样。基本上,这个过程就是发送和读取任何能够发送/读取的东西。如果没有可以读取的东西,它就中止读操作,做其他的事情直到能够读取为止。当发送数据时,该过程将试图发送所有的数据,但返回实际发送出的内容。可能是全部数据、部分数据或者根本没有发送数据。


阻塞与非阻塞相比确实有一些优点,特别是遇到错误控制问题的时候。在阻塞套接字通信中,如果出现错误,该访问会自动返回标志错误的代码。错误可能是由于网络超时、套接字关闭或者任何类型的 I/O 错误造成的。在非阻塞套接字通信中,该方法能够处理的唯一错误是网络超时。为了检测使用非阻塞通信的网络超时,需要编写稍微多一点的代码,以确定自从上一次收到数据以来已经多长时间了。


哪种方式更好取决于应用程序。如果使用的是同步通信,如果数据不必在读取任何数据之前处理的话,阻塞通信更好一些,而非阻塞通信则提供了处理任何已经读取的数据的机会。而异步通信,如 IRC 和聊天客户机则要求非阻塞通信以避免冻结套接字。

 

Java中的阻塞和非阻塞IO包各自的优劣思考 


NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式。 
反应器( Reactor ):用于事件多路分离和分派的体系结构模式  

通常的,对一个文件描述符指定的文件或设备 , 有两种工作方式 : 阻塞 与非阻塞 。所谓阻塞方式的意思是指 , 当试图对该文件描述符进行读写时 , 如果当时没有东西可读 , 或者暂时不可写 , 程序就进入等待 状态 , 直到有东西可读或者可写为止。而对于非阻塞状态 , 如果没有东西可读 , 或者不可写 , 读写函数马上返回 , 而不会等待  

一种常用做法是:每建立一个 Socket 连接时,同时创建一个新线程对该 Socket 进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。  

另一种较高效的做法是:服务器端保存一个 Socket 连接列表,然后对这个列表进行轮询,如果发现某个 Socket 端口上有数据可读时(读就绪),则调用该 socket 连接的相应读操作;如果发现某个 Socket 端口上有数据可写时(写就绪),则调用该 socket 连接的相应写操作;如果某个端口的 Socket 连接已经中断,则调用相应的析构方法关闭该端口。这样能充分利用服务器资源,效率得到了很大提高。  

传统的阻塞式 IO ,每个连接必须要开一个线程来处理,并且没处理完线程不能退出。  

非阻塞式 IO ,由于基于反应器模式,用于事件多路分离和分派的体系结构模式,所以可以利用线程池来处理。事件来了就处理,处理完了就把线程归还。而传统阻塞方式不能使用线程池来处理,假设当前有 10000 个连接,非阻塞方式可能用 1000 个线程的线程池就搞定了,而传统阻塞方式就需要开 10000 个来处理。如果连接数较多将会出现资源不足的情况。非阻塞的核心优势就在这里。  

为什么会这样,下面就对他们做进一步细致具体的分析:  

首先,我们来分析传统阻塞式 IO 的瓶颈在哪里。在连接数不多的情况下,传统 IO 编写容易方便使用。但是随着连接数的增多,问题传统 IO 就不行了。因为前面说过,传统 IO 处理每个连接都要消耗 一个线程,而程序的效率当线程数不多时是随着线程数的增加而增加,但是到一定的数量之后,是随着线程数的增加而减少。这里我们得出结论,传统阻塞式 IO 的瓶颈在于不能处理过多的连接。  

然后,非阻塞式 IO 的出现的目的就是为了解决这个瓶颈。而非阻塞式 IO 是怎么实现的呢?非阻塞 IO 处理连接的线程数和连接数没有联系,也就是说处理 10000 个连接非阻塞 IO 不需要 10000 个线程,你可以用 1000 个也可以用 2000 个线程来处理。因为非阻塞 IO 处理连接是异步的。当某个连接发送请求到服务器,服务器把这个连接请求当作一个请求 " 事件 " ,并把这个 " 事件 " 分配给相应的函数处理。我们可以把这个处理函数放到线程中去执行,执行完就把线程归还。这样一个线程就可以异步的处理多个事件。而阻塞式 IO 的线程的大部分时间都浪费在等待请求上了。  

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值