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的线程的大部分时间都浪费在等待请求上了。
[b]引用自:http://javag.javaeye.com

阻塞式IO就是在进行读写的时候调用了某个方法,如read()或write()方法
在该方法执行完之前,会一直等待,直到该方法执行完毕。所谓阻塞式IO流,就是指在从数据流当中读写数据的的时候,阻塞当前线程,直到IO流可以重新使用为止,你也可以使用流的avaliableBytes()函数看看当前流当中有多少字节可以读取,这样就不会再阻塞了。

Java code import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

public class ChannelInputStream extends InputStream {

private ReadableByteChannel channel;

public ChannelInputStream(ReadableByteChannel channel) throws IllegalArgumentException {
     if (channel == null ) {
       throw new IllegalArgumentException( " The readable byte channel is null " );
     }

this .channel = channel;
   }

public int read() throws IOException {
     ByteBuffer buffer = ByteBuffer.allocate( 1 );
     int result = channel.read(buffer);
     if (result != - 1 ) {
       buffer.flip();
       result = ( int ) buffer.get();
       buffer.clear();
     }
     return result;
   }

public int read( byte b[]) throws IOException {
     ByteBuffer buffer = ByteBuffer.allocate(b.length);
     int result = channel.read(buffer);
     if (result != - 1 ) {
       buffer.flip();
       buffer.get(b, 0 , result);
       buffer.clear();
     }
     return result;
   }

public int read( byte b[], int off, int len) throws IOException {
     ByteBuffer buffer = ByteBuffer.allocate(b.length);
     int result = channel.read(buffer);
     if (result != - 1 ) {
       buffer.flip();
       buffer.get(b, off, len > result ? result : len);
       buffer.clear();
     }
     return result;
   }

public void close() throws IOException {
     channel.close();
   }
}


什么是阻塞式和非阻塞io流?相关推荐

  1. java非阻塞io流_阻塞式和非阻塞io流初认识

    1  什么是阻塞式和非阻塞式? 阻塞式IO:IO即input/output,阻塞式IO指的是"一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成".在目前,我们从书本上 ...

  2. 阻塞式和非阻塞式udp传输_NIO非阻塞网络编程三大核心理念

    本次开始NIO网络编程,之前已经说过BIO,对于阻塞IO里面的问题一定有了清晰的认识,在JDK1.4版本后,提供了新的JAVA IO操作非阻塞API,用意替换JAVA IO 和JAVA NetWork ...

  3. 同步阻塞,同步非阻塞,异步阻塞,异步非阻塞IO

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...

  4. 同步阻塞与异步非阻塞

    syncBlocking & asyncNonblocking 转载:https://www.zhihu.com/question/19732473/answer/23434554 作者:严肃 ...

  5. Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结

    同步和异步:与消息的通知机制有关. 本质区别 现实例子 同步模式 由处理消息者自己去等待消息是否被触发 我去银行办理业务,选择排队等,排到头了就办理. 异步模式 由触发机制来通知处理消息者 我去银行办 ...

  6. 嵌入式驱动之阻塞操作、非阻塞操作

    阻塞 阻塞操作     是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作. 被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足. 非阻塞操作   进 ...

  7. 深入理解阻塞socket和非阻塞socket

    什么是阻塞socket,什么是非阻塞socket.对于这个问题,我们要先弄清什么是阻塞/非阻塞.阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式. 阻塞的意思是指,当试图对该文件描述符进行 ...

  8. python非阻塞输入_python_非阻塞套接字及I/O流

    首先,我们要明确2个问题: 普通套接字实现的服务端有什么缺陷吗? 有,一次只能服务一个客户端! 这种缺陷是如何造成的? accept阻塞:当没有套接字连接请求过来的时候会一直等待着 recv阻塞:当连 ...

  9. 同步阻塞、同步非阻塞、异步阻塞、异步非阻塞与 I/O 多路复用、Java NIO 之间的联系

    同步阻塞.同步非阻塞.异步阻塞.异步非阻塞与 I/O 多路复用.Java NIO 之间的联系 先验知识 此处的异步指的是什么 同步.异步.阻塞.非阻塞 同步阻塞.同步非阻塞.异步阻塞.异步非阻塞 一个 ...

最新文章

  1. 图像集存储成MNIST数据集格式实现
  2. Exchange 2013部署系列之(七)配置SSL多域名证书
  3. DPDK vhost-user研究(九)
  4. 剑指Offer——二叉树的镜像
  5. mysql sleep详解_sql注入详解(二)
  6. cesiumjs开发实践(七) 3D模型
  7. Linux 计算器程序
  8. 1386 安排电影院座位(字典、位运算)
  9. 库存成本计算方法简介
  10. 不同shp图层合在一起_ps怎么把别的图层的合到一起
  11. 想知道微信怎么做指纹支付开发?看这里!
  12. Avoid passing null as the view root (needed to resolve layout parameters on the inflated layout's ro
  13. Ubuntu出现System policy prevents modification of network settings for all users该怎么解决
  14. 家庭电脑虚拟机安装Linux,外网电脑无法远程控制的解决方法
  15. 电子器件选型:保险丝
  16. 网络与信息安全学习(七)
  17. 汉诺塔问题(Towers of Hanoi)
  18. IEC的PLC编程语言标准 IEC61131-3
  19. 【云计算课程】Lecture 1 云计算概述
  20. 手机浏览计算机以查找驱动程序,mtk智能机usb驱动安装教程

热门文章

  1. 透彻分析JAVA内存泄漏和内存溢出的区别
  2. 中英文排版字符间距不一致,英文自动断字
  3. 高通量测序的数据处理与分析指北(一)_network
  4. mysql证书有哪些_mysql证书叫什么
  5. Java实现输出100-1000的水仙花数
  6. 总结java重载和重写的区别
  7. 唯样商城:英飞凌 —— 一文弄懂IGBT驱动
  8. Seq2Seq Attention模型
  9. 定位综合案例-淘宝轮播图
  10. Linux命令:Nginx的启动、停止与重启