当前位置: 首页 > 编程日记 > 正文

Java BIO、NIO、AIO

同步与异步

同步与异步的概念, 关注的是 消息通信机制

  • 同步是指发出一个请求, 在没有得到结果之前该请求就不返回结果, 请求返回时, 也就得到结果了.

比如洗衣服, 把衣服放在洗衣机里, 没有洗好之前我们一直看着, 直到洗好了才拿出来晾晒.

  • 异步是指发出一个请求后, 立刻得到了回应, 但没有返回结果. 这时我们可以再处理别的事情(发送其他请求), 所以这种方式需要我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者.

比如洗衣服时, 把衣服放到洗衣机里, 我们就可以去做别的事情, 过会儿来看看有没有洗好(通过状态查询); 
或者我们设置洗衣机洗完后响铃来通知我们洗好了(回调通知)


阻塞与非阻塞

阻塞与非阻塞很容易和同步与异步混淆, 但两者关注点是不一样的. 阻塞与非阻塞关注的是 程序在等待调用结果时的状态

  • 阻塞是指请求结果返回之前, 当前线程会被挂起(被阻塞), 这时线程什么也做不了
  • 非阻塞是指请求结果返回之前, 当前线程没有被阻塞, 仍然可以做其他事情.

阻塞有个明显的特征就是线程通常是处于BLOCKED状态(BIO中的read()操作时, 线程阻塞是JVM配合OS完成的, 此时Java获取到线程的状态仍是RUNNABLE但它确实已经被阻塞了)

如果要拿同步来做比较的话, 同步通信方式中的线程在发送请求之后等待结果这个过程中应该处于RUNNABLE状态, 同步必须一步一步来完成, 就像是代码必须执行完一行才能执行下一行, 所以必须等待这个请求返回之后才可进行下一个请求, 即使等待结果的时间长, 也是在执行这个请求的过程中. 而异步则不用等上一条执行完, 可以先执行别的代码, 等请求有了结果再来获取结果.


IO模型

Java中的IO操作是JVM配合操作系统来完成的. 对于一个IO的读操作, 数据会先被拷贝到操作系统内核的缓冲区中, 然后从操作系统内核的缓冲区拷贝到应用程序的地址空间. 所以整个过程可分为两个阶段:

  1. 等待I/O数据准备好. 这取决于IO目标返回数据的速度, 如网络IO时看网速和数据本身的大小.
  2. 数据从内核缓冲区拷贝到进程内.

根据这两个阶段, 产生了常见的几种不同的IO模型: BIONIOIO多路复用AIO.

BIO

BIOBlocking I/O(阻塞 I/O), BIO整个过程如下图:

BIO

程序发送请求给内核, 然后由内核去进行通信, 在内核准备好数据之前这个线程是被挂起的, 所以在两个阶段程序都处于挂起状态.

  • BIO的特点就是在IO执行的两个阶段都被block了

NIO

NIONon-Blocking I/O(非阻塞 I/O), NIO整个过程如下图:

NIO

与BIO的明显区别是, 发起第一次请求后, 线程并没有被阻塞, 它反复检查数据是否准备好, 把原来大块不能用的阻塞时间分成了许多”小阻塞”(检查), 所以进程不断有机会被执行. 这个检查有没有准备好数据的过程有点类似于”轮询”.

  • NIO的特点就是程序需要不断的主动询问内核数据是否准备好。第一个阶段非阻塞, 第二个阶段阻塞

IO多路复用

IO多路复用(I/O Multiplexing)有selectpollepoll等不同方式, 它的优点在于单个线程可以同时处理多个网络IO.

NIO中轮询操作是用户线程进行的, 如果把这个任务交给其他线程, 则用户线程就不用这么费劲的查询状态了. IO多路复用调用系统级别的selectpoll模型, 由系统进行监控IO状态. select轮询可以监控许多socket的IO请求, 当有一个socket的数据准备好时就可以返回.

  • select: 注册事件由数组管理, 数组是有长度的, 32位机上限1024, 64位机上限2048. 轮询查找时需要遍历数组.
  • poll: 把select的数组采用链表实现, 因此没了最大数量的限制
  • epoll方式: 基于事件回调机制, 回调时直接通知进程, 无须使用某种方式来查看状态.

多路复用IO过程图:

Multiplexing_IO

用户线程有一段时间是阻塞的, 从上图来看, 与NIO很像, 但与NIO不一样的是, select不是等到所有数据准备好才返回, 而是只要有一个准备好就返回, 它的优势在于可以同时处理多个连接. 若连接不是很多的话, 它的效率不一定高, 可能还会更差.

Java 1.4开始支持NIO(New IO), 就是采用了这种方式, 在套接字上提供selector选择机制, 当发起select()时会阻塞等待至少一个事件返回.

  • 多路复用IO的特点是用户进程能同时等待多个IO请求, 系统来监控IO状态, 其中的任意一个进入读就绪状态, select函数就可以返回.

AIO

AIOAsynchronous I/O(异步 I/O), 这是Java 1.7引入的NIO 2.0中用到的. 整个过程中, 用户线程发起一个系统调用之后无须等待, 可以处理别的事情. 由操作系统等待接收内容, 接收后把数据拷贝到用户进程中, 最后通知用户程序已经可以使用数据了, 两个阶段都是非阻塞的. AIO整个过程如下图:

AIO

AIO属于异步模型, 用户线程可以同时处理别的事情, 我们怎么进一步加工处理结果呢? Java在这个模型中提供了两种方法:

  1. 一种是基于”回调”, 我们可以实现CompletionHandler接口, 在调用时把回调函数传递给对应的API即可
  2. 另一种是返回一个Future. 处理完别的事情, 可以通过isDone()可查看是否已经准备好数据, 通过get()方法等待返回数据.

小结

上面这几种模式, BIO整个过程都等待返回, NIOIO多路复用在第二个阶段等待返回, 因此从整个过程来看, 这三个模式都属于同步方式. AIO在整个过程中没有等待返回, 属于异步方式.

相关文章:

LeetCode实战:数组中的第K个最大元素

背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Find the kth largest element in an unsorted array. Note that it is the kth largest el…

热修复测试过程注意事项

软件测试行是近几年比较火热的技术岗位,想要学习软件测试的同学有很多,今天小编给你分析一下关于热修复测试过程注意事项的相关内容,如果你在一次测试中脱颖而出那将来的你一定很精彩! 基于tinker实际测试过程中遇到的问题,小编简…

LeetCode实战:存在重复元素

背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Given an array of integers, find if the array contains any duplicates. Your function…

oracle exec 和 call 区别

转自:http://helloaq.iteye.com/blog/221614 exec 和 call 执行一个procedure时, exec是sqlplus的命令,只能在sqlplus中使用。 call是sql命令,任何工具都可以使用转载于:https://www.cnblogs.com/zerocc/archive/2011/07/27/21189…

html简单响应式滚动条置顶

简单响应式滚动条置顶 一般的,让页面出现滚动条的常见方法有: overflow:auto||overflow:scroll 或者overflow-x水平滚动条和overflow-y垂直滚动条那么现在要实现这样的一个效果: 直接在body中给一个header,后面一个Group盒子&…

UI设计培训之:5个小技巧快速学会PS抠图

一听到PS抠图,我们大家心里是不是产生了退却心理,害怕它过于复杂的操作。 那么现在有一种简单方法教给大家,如何在10分钟内快速学会ps抠图。 而你所需要准备的就是给自己10分钟的尝试时间。 你没有尝试过某件事情,就不要轻易说它难…

AIX VNC setup

1. 下载VNC for AIX虽然标明是for AIX51的,但AIX53和AIX61仍可用。 2. 安装RPM: rpm -Uhv vnc-3.3.3r2-3.aix5.1.ppc.rpm 3.编辑配置文件: # which vncserver/usr/bin/X11/vncserver #chmod 777 /usr/binX11/vncserver vi /usr/bin/X11/vncserver 更改前…

历史 history

题目描述 历史学家小A正在研究一个奇怪的王国的历史。当前阶段的任务是研究该国的交通。 根据这个奇怪的王国的史书记载,史书开始记载前这个王国有 n 个城市(城市从 0 开 始标号) ,但所有城市之间都没有道路相连。 …

LeetCode实战:Nim 游戏

背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 You are playing the following Nim Game with your friend: There is a heap of stones on…

python值得报班学习吗

python值得报班学习吗?最近有很多想要学习Python的同学都会问到这个问题,Python在近几年的发展前景是非常不错的,想要学会Python编程语言,建议还是报班学习,来看看下面的详细介绍吧。 ​  python值得报班学习吗?首先Python值不…

LeetCode实战:2的幂

背景 为什么你要加入一个技术团队?如何加入 LSGO 软件技术团队?我是如何组织“算法刻意练习活动”的?为什么要求团队的学生们写技术Blog 题目英文 Given an integer, write a function to determine if it is a power of two. Example 1: …

P1214 等差数列

https://www.luogu.org/problem/show?pid1214#sub 暴力枚举题&#xff0c;加上一些剪枝。 &#xff08;原谅我卑劣地提交了两个答案特判&#xff09; #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorit…

cocos2d 0.99.5版本屏幕默认是横屏,怎么修改为竖屏呢?

在RootViewController.m文件里面&#xff0c;修改如下代码#elif GAME_AUTOROTATION kGameAutorotationUIViewController // // EAGLView will be rotated by the UIViewController // // Sample: Autorotate only in landscpe mode // // return YES for th…

学习java三个技巧要知道!

java一直是IT行业发展前景非常不错的一门编程语言&#xff0c;学起来是相对有点困难的&#xff0c;尤其是零基础学员&#xff0c;要想学好java技术&#xff0c;一定要知道这三个技巧&#xff0c;来看看下面的详细介绍就知道了。 学习java三个技巧要知道! 1. 树立学习的信心 很多…

LeetCode实战:格雷编码

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 The gray code is a binary numeral system where two successive values differ in only o…

Programmer of Practice Manual

这是我以前再读研究生的时候写的东东&#xff0c;希望搞计算机的同学&#xff0c;教计算机本科生学习技术的文章&#xff08;非算法类&#xff09;粘在这里纪念一下。 大一寒假 结构化编程基础&#xff1a; 图书&#xff1a;《How to C》 实践过程&#xff1a;完成课后的习题&a…

改善C#程序的建议3:在C#中选择正确的集合进行编码

原文:改善C#程序的建议3&#xff1a;在C#中选择正确的集合进行编码要选择正确的集合&#xff0c;我们首先要了解一些数据结构的知识。所谓数据结构&#xff0c;就是相互之间存在一种或多种特定关系的数据元素的集合。结合下图&#xff0c;我们看一下对集合的分类。 集合分类 …

Python工程师求职必知的经典面试题

最近几年&#xff0c;学习Python语言的同学越来越多&#xff0c;学成之后大家对于后期的面试都遇到了很多难题&#xff0c;小编这次为大家整理了一份关于Python工程师求职必知的经典面试题!希望能够帮助到正在找Python工作的同学们。 Python工程师求职必知的经典面试题&#xf…

LeetCode实战:二叉树中的最大路径和

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Given a non-empty binary tree, find the maximum path sum. For this problem, a path i…

为Visual Studio添加配色方案

看到网上有一些教程&#xff0c;他们的代码截图&#xff0c;不是VS默认的白底黑字&#xff0c;觉得挺好看&#xff0c;就也把自己的VS鼓捣了一把&#xff1a; 使用的是现成的配色方案&#xff0c;试了好几种&#xff0c;就觉得这个看着舒服son-of-obsidian.vssettings 你可以去…

黑色星期五阿里云向海淘输出双11技术

本文讲的是"黑色星期五"阿里云向海淘输出双11技术【IT168资讯】11月27日零点&#xff0c;“黑色星期五”正式到来&#xff0c;虽然远在中国的消费者无法参与海外的实体抢购&#xff0c;但电商平台却给了他们从地球另一端参与“大抢购”的机会。随着近年海淘市场的不断…

专业的java培训机构是否靠谱,对比一下就知道了!

java在IT行业的火热是有目共睹的&#xff0c;所以市面上有很多机构都抓住了这点&#xff0c;开设了java培训课程&#xff0c;想要找到一个适合自己的java培训机构&#xff0c;多进行对比就知道了! 专业的java培训机构是否靠谱&#xff0c;对比一下就知道了!专业的Java培训机构靠…

LeetCode实战:环形链表 II

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Given a linked list, return the node where the cycle begins. If there is no cycle, re…

.NET中使用OracleHelper

以前一直使用MSSQL,数据库操作类也是自己写的.现在项目使用Oracle,数据库操作类用的是MICROSOFT的DAAB中的OracleHelper.实际使用过程中,发现坛内少有此方面使用经验的贴子,故在这里把我使用中的一点经验用几个例子说明一下,希望起到抛砖引玉的作用. 查询数据方面: 1.简单的SQL…

新勒索软件DynA-Crypt不仅要加密你的文件,而且窃取并删除它们

本文讲的是新勒索软件DynA-Crypt不仅要加密你的文件&#xff0c;而且窃取并删除它们&#xff0c;一个名为DynA-Crypt的新勒索软件被GData公司的恶意软件分析师Karsten Hahn发现&#xff0c;DynA-Crypt不仅能加密你的数据&#xff0c;而且试图从受害者的计算机窃取大量信息。虽然…

【Postman】6 Postman 发送post请求-Json格式

一、post请求说明 使用postman发送一个post请求&#xff0c;在上文中测试流程中提到的4个要素&#xff1a;URL、请求方式、请求头部信息及body数据。 body中设置的请求参数&#xff0c;常见的有如下三种&#xff1a; 1、x-www-from-urlencoded格式 2、form data格式 3、Json格式…

LeetCode实战:最小栈

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Design a stack that supports push, pop, top, and retrieving the minimum element in co…

配置国内 Docker Registry Mirror

由于国内特殊的网络环境&#xff0c;往往我们从Docker Hub中拉取镜像并不能成功&#xff0c;而且速度特别慢。 那么我们可以给Docker配置一个国内的registry mirror&#xff0c;当我们需要的镜像在mirror中则直接返回&#xff0c;如果没有则从Docker Hub中拉取。是否使用regist…

Java培训深度学习都要学什么

java的知识点有很多&#xff0c;如果是有java基础的同学&#xff0c;进行深度学习是非常有必要的&#xff0c;比较职场技能更新迭代非常的快&#xff0c;那么java培训深度学习都要学什么呢?来看看下面的详细介绍。 Java培训深度学习都要学什么? Java深度学习要掌握两点&#…

LeetCode实战:相交链表

背景 为什么你要加入一个技术团队&#xff1f;如何加入 LSGO 软件技术团队&#xff1f;我是如何组织“算法刻意练习活动”的&#xff1f;为什么要求团队的学生们写技术Blog 题目英文 Write a program to find the node at which the intersection of two singly linked lists…