码迷,mamicode.com
首页 > 编程语言 > 详细

java nio aio bio概念

时间:2021-06-28 20:08:59      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:高效   傻傻   游戏服务器   sel   accept   date   原来   str   and   


title: java nio aio bio概念
date: 2018/1/13 21:12:55
tags: [nio,aio]
categories:

  • 开发
  • java

就目前来说,大多数的系统瓶颈在io , io的瓶颈又在寻址 ……

跑题了,我先来记录总结几个基本概念吧

IO分两阶段:

1.数据准备阶段
2.内核空间复制回用户进程缓冲区阶段

一般来讲:阻塞IO模型、非阻塞IO模型、IO复用模型(select/poll/epoll)、信号驱动IO模型都属于同步IO,因为阶段2是阻塞的(尽管时间很短)。只有异步IO模型是符合POSIX异步IO操作含义的,不管在阶段1还是阶段2都可以干别的事。

阻塞和非阻塞

是进程访问数据的时候,数据是否准备就绪的一种处理方式 。

当数据没有准备好的时候:

  • 阻塞

    需要等待数据缓冲区中的数据准备好后,才处理其它事情

  • 非阻塞

    数据如果没有准备好,直接返回

同步和异步

基于应用程序操作系统处理io事件所采用的方式

  • 同步

    1. 应用程序直接参与io读写的操作

    2. 会阻塞在某个方法上等待io事件的完成(阻塞io事件 或者 通过轮询方式)

      • 阻塞io事件

        不能做自己的事情,一直阻塞线程

      • IO事件轮询方式(多路复用,Select模式)

        读写事件交给一个单独的(select)线程来处理,并完成io事件的注册功能 ,然后不断的轮询读写缓冲区看数据是否准备好,有数据通知我们的读写线程 。这样以前的读写线程可以做其它事情 ,因为这个时候阻塞的不是所有的io线程,而是select线程 (select 相当于一个管家)

        但是它还是同步的,因为真正的io操作不是完全交给操作系统的,应用程序要参与

      • 例子(把select比做管家,还有客人和主人):

        当【客人】来拜访【主人】的时候,先找到【管家】,【管家】得到这个注册信息后,跟【主人】说:我这里来了一个或者多个【客人】,他们需要【主人】给他们某某东西 。这个时候【客人】可以去做其它事情,比如看看花园 。当【管家】得知【主人】准备好东西后,他就去找对应的某人 告诉这位【客人】主人给他某样东西 ,这个时候阻塞是发生在 【管家】不是【客人】

  • 异步

    1. 所有的io操作交给OS处理

    2. 可以去做其它事情,并不需要去完成真正的io操作,当操作系统完成io后,给我们应用程序一个通知就行

  • 例子(来源于网络)阻塞和非阻塞,同步和异步

    故事:老王烧开水。

    出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。

    老王想了想,有好几种等待方式

    1. 老王用水壶煮水,并且站在那里不管水开没开,每隔一定时间看看水开了没。-同步阻塞

    老王想了想,这种方法不够聪明。

    1. 老王还是用水壶煮水,不再傻傻的站在那里看水开,跑去寝室上网但是还是会每隔一段时间过来看看水开了没有,水没有开就走人。-同步非阻塞

    老王想了想,现在的方法聪明了些,但是还是不够好。

    1. 老王这次使用高大上的响水壶来煮水,站在那里但是不会再每隔一段时间去看水开,而是等水开了,水壶会自动的通知他。-异步阻塞

    老王想了想,不会呀,既然水壶可以通知我,那我为什么还要傻傻的站在那里等呢,嗯,得换个方法。

    1. 老王还是使用响水壶煮水,跑到客厅上网去,等着响水壶自己把水煮熟了以后通知他。-异步非阻塞

    老王豁然,这下感觉轻松了很多。

JAVA IO模型

BIO

graph TD Thread((Thread1)) --read-->InputStream1; InputStream1 --io-->Socket1; Thread2((Thread2)) --read-->InputStream2; InputStream2 --io-->Socket2; Thread3((Thread3)) --read-->InputStream3; InputStream3 --io-->Socket3;

JDK1.4以前都是使用的bio

  • 阻塞在读写方法
  • 用阻塞到线程来改进性能,但是线程也是一个大的开销
  • 阻塞点
    • server.accept()
    • inputstream.read()
  • 缺点
    • 单线程情况下只能有一个客户端访问
    • 用线程池可以有多个客户端连接,但是非常消耗性能

NIO

graph LR; Thread((Thread))--select-->Selector; SocketChannel1--register-selectionkey-->Selector; SocketChannel2--register-selectionkey-->Selector; SocketChannel3--register-selectionkey-->Selector; SocketChannel1--io-->Socket1; SocketChannel2--io-->Socket2; SocketChannel3--io-->Socket3;

New IO,Single thread blocked on selection

阻塞点
  • selector.select();//当注册的事件到达时 该方法返回 ,否则一直阻塞
  • select()也可以不阻塞 ,select(millisecond) wakeup() selectNow()
  • 单线程可以服务多个客户端
Select模式
  • 学习了linux的多路复用技术
  • "多路复用" --这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗)
  • 如果你看select()方法的实现 你会发现:它是用c写的
    • windows通过winsocket实现
    • linux通过select/poll/epoll实现
  • 同步非阻塞 nio v1
  • 实现IO事件的轮询方式
  • 常用的网络通信框架 mina,netty
原理

selector要管理的事情:(所有的io事件)

  • 客户端的连接
  • 服务端的accept
  • 客户端和服务端的读写

选择器:当io事件注册给我们的selector时,selector会分配一个key标记它,当io事件完成时通过这个标记来找到相应的管道,然后通过管道来发送和接收数据等操作

数据缓冲区:bytebuffer 提供很多读写方法

重要API:

// Selector
Selector select = Selector.open();
// Server point 
ServerSocketChannel
// client point
SocketChannel 
// 获取io事件keys 
Selectionkey keys = Selector.selectedKeys();

// 注册到selector
channel.register(Selector,SelectedKeys.OP_WRITE)

例子
  • 客人到餐厅点菜

  • 餐厅(系统) ; 餐厅大门(ServerSocketChannel); 客人(客户端-SocketChannel); 服务员(selector + 线程);

AIO

  • jdk1.7以后 nio v2

  • 学习了linux epoll 模式

  • 原理

    • AsynchronousServerSocketChannel

    • AsynchronousSocketChannel

    • 用户处理器:interface CompletionHandler

      • 这个接口向操作系统发起IO请求,当完成后处理具体逻辑,否则做自己该做的事情
      • completed(V result, A attachment)方法
      • fail(Throwable exc result, A attachment)方法

小结

  • NIO AIO 原理就是在原来的(serversocket,socket)基础上做了改进
    • 对读写管道进行了抽象,管道Channel
    • 一个连接(TCP,UDP) 可以对应有多个管道

Netty

运用在那些领域?

  1. 分布式进程通信
    例如: hadoop、dubbo、akka , rocketmq等具有分布式功能的框架,底层RPC通信都是基于netty实现的
  2. 游戏服务器开发

详细的另外的文章再写吧

java nio aio bio概念

标签:高效   傻傻   游戏服务器   sel   accept   date   原来   str   and   

原文地址:https://www.cnblogs.com/skystarry/p/14941330.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!