BIO

JDK1.4推出NIO1.0

同步阻塞模式(BIO):一请求一应答的通信模型,弊端:面对访问量的激增,只能硬件扩容

BIO的服务端通信模型

1.通常由一个独立的Acceptor线程负责监听客户端的连接

2.接收到客户端连接请求之后,为客户端连接创建一个新的线程处理请求的消息

3.处理请求后,返回应答消息给客户端,线程销毁

一个线程处理一个Socket连接,因为Java Socket是通过InputStream和OutputStream来进行网络读写操作,而这俩个的读写都是阻塞模式,所以当某个Socket链路的读写操作没有完成时,排在后面的Socket连接是无法得到处理的,长时间的等待可能会导致超时,因此在同步阻塞模式下,通常会采用一个Socket链路独占一个线程的模型。

 

对BIO的优化:

采用线程池和任务队列实现一种叫做伪异步的IO通信框架

服务端接收到客户端的连接时,不创建独立的线程,而是将Socket连接封装成Task,将Task放入线程池的任务队列中执行,这样就可以有效控制线程的规模,防止线程膨胀导致的系统崩溃,利用线程池,可以重用线程,相比于BIO,性能有很大提高。

弊端:无法从根本上解决问题,由于IO读写会被阻塞,当并发量激增或者网络时延增大之后,线程的执行时间会被拉长,它导致缓存在任务队列中的任务不断堆积,最终导致内存溢出或者拒绝新任务的执行。

 

JDK1.4之后推出非阻塞IO(NIO)

NIO API主要由三部分组成:缓冲区(Buffers)、通道(Channels)和Selector组成

NIO 是基于事件驱动思想实现的,它采用Reactor模式实现,主要用来解决BIO模型中一个服务端无法同时并发处理大量客户端连接的问题。

NIO 基于Selector进行轮询,当socket有数据可读、可写、连接完成、新的TCP请求接入事件时,操作系统内核会触发Selector返回准备就绪的SelectionKey的集合,通过SelectableChannel进行读写操作。

SelectableChannel的读写操作都是异步非阻塞的,当由于数据没有就绪导致读半包时,立即返回,不会同步阻塞等待数据就绪,当TCP缓冲区数据就绪之后,会触发Selector的读事件,驱动下一次读操作。

 

posted @ 2016-06-20 11:54  薛晓东  阅读(412)  评论(0编辑  收藏  举报