星球狂想战队|深度解读Netty:NIO那些不为人知的秘密( 二 )


阻塞和非阻塞
阻塞:阻塞就是发起一个请求 , 调用者一直等待请求结果返回 , 也就是当前线程会被挂起 , 无法从事其他任务 , 只有当条件就绪才能继续 。 非阻塞:非阻塞就是发起一个请求 , 调用者不用一直等着结果返回 , 可以先去干其他事情 。阻塞和非阻塞是针对进程在访问数据的时候 , 根据IO操作的就绪状态来采取的不同方式 , 说白了是一种读取或者写入操作方法的实现方式 , 阻塞方式下读取或者写入函数将一直等待 , 而非阻塞方式下 , 读取或者写入方法会立即返回一个状态值 。
如果组合后的同步阻塞(blocking-IO)简称BIO、同步非阻塞(non-blocking-IO)简称NIO和异步非阻塞(asynchronous-non-blocking-IO)简称AIO又代表什么意思呢?
BIO(同步阻塞I/O模式):数据的读取写入必须阻塞在一个线程内等待其完成 。 这里使用那个经典的烧开水例子 , 这里假设一个烧开水的场景 , 有一排水壶在烧开水 , BIO的工作模式就是 , 叫一个线程停留在一个水壶那 , 直到这个水壶烧开 , 才去处理下一个水壶 。 但是实际上线程在等待水壶烧开的时间段什么都没有做 。 NIO(同步非阻塞):同时支持阻塞与非阻塞模式 , 但这里我们以其同步非阻塞I/O模式来说明 , 那么什么叫做同步非阻塞?如果还拿烧开水来说 , NIO的做法是叫一个线程不断的轮询每个水壶的状态 , 看看是否有水壶的状态发生了改变 , 从而进行下一步的操作 。 AIO(异步非阻塞I/O模型):异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变 , 在相应的状态改变后 , 系统会通知对应的线程来处理 。 对应到烧开水中就是 , 为每个水壶上面装了一个开关 , 水烧开之后 , 水壶会自动通知我水烧开了 。java中的BIO、NIO和AIO理解为是Java语言在操作系统层面对这三种IO模型的封装 。 程序员在使用这些封装API的时候 , 不需要关心操作系统层面的知识 , 也不需要根据不同操作系统编写不同的代码 , 只需要使用Java的API就可以了 。 由此 , 为了使读者对这三种模型有个比较具体和递推式的了解 , 并且和本文主题NIO有个清晰的对比 , 下面继续延伸 。
JavaBIO
BIO编程方式通常是是Java的上古产品 , 自JDK1.0-JDK1.4就有的东西 。 编程实现过程为:首先在服务端启动一个ServerSocket来监听网络请求 , 客户端启动Socket发起网络请求 , 默认情况下SeverSocket会建立一个线程来处理此请求 , 如果服务端没有线程可用 , 客户端则会阻塞等待或遭到拒绝 。 服务器实现模式为一个连接一个线程 , 即客户端有连接请求时服务器端就需要启动一个线程进行处理 。 大致结构如下: