上图是NIO的线程模型, 基于select实现, 这种线程模型的特色: 多条channel经过一个选择器和单挑线程绑定, 而且在这种编程模型中, Channel中相关业务逻辑不容许存在耗时的任务 , 若是必定会有耗时的逻辑, 请将它们放置到线程池中去运行, 由于这种模型虽然作到了非阻塞, 可是他并非真正的异步编程, 任何channel上的任何耗时的操做, 都会拖垮这个选择器, 进而拖垮整条线程 , 这也是为啥它会被称为 同步非阻塞java
select()
会同步等待选择器感兴趣的事件发生NIO线程线程模型相对于传统的BIO来讲, 最大的优点就是在于 NIO线程模型中单条线程可同时为N个用户(Channel)服务, 而BIO编程模型让人诟病的地方就是, 任何一个新链接接入, 服务器都得为他开启不止一条新的线程去运行它, 这种BIO系统中, 并发确定不会很高编程
NIO方式适用于链接数目多且链接比较短(轻操做)的架构,好比聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持服务器
AIO是(jdk1.7) 发行的 异步IO编程模型, 真正实现了异步IO, 基于Linux系统的 Epoll 机制实现网络
不管是NIO, 仍是AIO底层都没有改变网络通讯的基本步骤, 而是在这个基础上进行了一系列的升级架构
AIO的底层实现是由操做系统完成的, 数据在内核空间&用户空间的迁移, 咱们在编写代码时也是这样, 只须要调用 AIO.read()
或者是 AIO.write()
便可, 换句话说, 咱们的业务逻辑就成了 回调, 原来在操做系统处理数据的这个过程当中, 咱们的程序须要阻塞等待着, 亦或者放在线程池中运行, 而在AIO编程中这段等待时间差被省去了, 由于当操做系统认为数据还有没准备完时, 它是不会打扰咱们的程序的, 这时咱们的程序能够去处理其余的逻辑, 而一旦操做系统认为数据齐全了, 他就会回调咱们的提供的回调函数并发
下面贴出来一个AIO编程Server端的实例:异步
像下面的 read() write() accept() 全是异步的, 一经调用即刻返回, 不同的地方是咱们会提供一个回调对象, 留给操做系统, 当操做系统认为读写数据都到位了, 就会去回调这些函数async
public class AIOServer { private ExecutorService executorService; // 服务端的Channel private AsynchronousServerSocketChannel asynchronousServerSocketChannel; private AIOServer(int port) { init(port); } // 初始化 private void init(int port) { System.out.println("aio server start with port " + port); executorService = Executors.newFixedThreadPool(5); try { // 开启服务端的通道 asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open(); // 绑定端口 asynchronousServerSocketChannel.bind(new InetSocketAddress(port)); System.out.println("server start ... "); /** * 方法会异步的去接收一个请求, accept()一样是 * 参数1 : this , 暂时理解成任意类型的 * 参数2 : CompleteHandler -- 当请求到来后,会交付给 AIOServerHandler进行处理 * * todo 在 AIO中的监听并非while(true), 而是相似递归的操做, 每次监听到客户端的请求后, 都须要在处理逻辑中开启下一次的监听 */ asynchronousServerSocketChannel.accept(this, new AIOServerHandler()); System.out.println("------------------------------"); // 阻塞程序 try { TimeUnit.SECONDS.sleep(60); } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } public AsynchronousServerSocketChannel getAsynchronousServerSocketChannel() { return this.asynchronousServerSocketChannel; } public static void main(String[] args) { AIOServer aioServer = new AIOServer(9999); } }
AIO方式使用于链接数目多且链接比较长(重操做)的架构,好比相册服务器,充分调用OS参与并发操做,编程比较复杂,JDK7开始支持。异步编程
我是bloger 赐我白日梦, 欢迎关注我 --武汉加油函数