本文总结自
 
 
快速理解
首先,我们要先对这几个概念有一个直观的理解,对于初学者来说,你可以这样看待这几个概念:
  • 阻塞非阻塞 指的是在客户端

    • 阻塞:意味着 客户端提出一个请求以后,在得到回应之前,只能等待
    • 非阻塞:意味着 客户端提出一个请求以后,在得到回应之前,客户端还可以做其他事情
  • 同步异步 指的是服务器端
    • 同步:意味着 服务器接受一个请求后,在返回结果以前不能做其他的事情
    • 异步:意味着 服务器接受一个请求后,尽管还没有返回结果,但是可以做其他的事情
这样的理解其实是过于以偏概全的,因为这只是消息通知场景中的解释,但是通过代入客户端,服务器端更加方便初学者理解,因此在这里,暂且先这样解释。
 
 
举个例子
小明领着女朋友去超市购物,买了很多东西,当他走到收银员那里结账的时候,小明(客户端)发出了要求结账的讯息(请求),收银员(服务器)会对他这一要求进行处理。此时有可能产生多种场景
  • 小明傻傻地等着收银员用计算器算出所有物品的总价,并准备付款。(同步阻塞:小明在请求响应之前,一直在等待;收银员没有做别的事情,一直在处理小明的请求)
  • 小明觉得自己太傻了,于是一边和女朋友聊天,一边催促收银员快点计算出总价。(同步非阻塞:小明在请求响应之前,做了其他的事情;收银员一直在处理小明的请求)
  • 小明傻傻地等着收银员的总价结果,收银员却把计算的工作交给计算机之后就去拿袋子帮忙装东西,直到计算机上出现了总价结果,收银员才继续回来完成收款工作。(异步阻塞:小明在请求响应之前,一直在等待;收银员在处理小明请求的过程中,处理了其他的事情)
  • 小明觉得自己太傻了,于是一边和女朋友聊天,一边催出收银员快点计算出总价,而收银员却把计算的工作交给计算机之后就去拿袋子帮忙装东西,直到计算机上出现了总价结果,收银员才继续回来完成收款工作。(异步非阻塞:小明在请求响应之前做了其他的事情;收银员也在处理请求的过程中,处理了其他的事情)
在这个例子中:
  • 阻塞,非阻塞,指的是小明是否在等待处理结果的过程中去做了其他的事情。
  • 同步,异步,指的是收银员是否在处理收款这一请求的过程中去做了其他的事情,这也导致了收款的结果是当时告诉了小明,还是之后又进行了额外的通知。
 
再来个例子
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
  1. 老张把水壶放到火上,立等水开。(同步阻塞)老张觉得自己有点傻
  2. 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的响声。
  3. 老张把响水壶放到火上,立等水开。(异步阻塞)老张觉得这样傻等意义不大
  4. 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞
在这个例子中:
  • 所谓同步异步,只是对于水壶而言。

    • 普通水壶,同步;响水壶,异步。
    • 虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
    • 同步只能让调用者老张去轮询自己(情况2中),造成老张效率的低下。
  • 所谓阻塞非阻塞,仅仅对于老张而言。
    • 立等的老张,阻塞;看电视的老张,非阻塞。
    • 情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。
一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
 
 
结论:
阻塞和非阻塞:关注的是调用者是否会一直等待被调用者的通知。换句话说,发出请求者是否会在等待过程中去做别的事情。
同步和异步:关注的是被调用者是否会一直处理该请求。换句话说,处理请求者是持续处理该请求并通过原调用将结果返回,还是可以在该请求处理完成前处理其他事情,并在该请求完成时通过其他方式将结果通知调用者。
 
 
深入探究
一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作。
阻塞IO和非阻塞IO的区别在于发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
同步IO和异步IO的区别就在于实际的IO操作是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO。
 
阻塞和非阻塞是针对于进程在访问数据的时候,根据IO请求的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入函数会立即返回一个状态值。
同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发IO操作并等待或者轮询(轮询的时候不干别的事情)的去查看IO操作是否就绪,而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。
 
所以,IO操作可以分为3类:同步阻塞(即早期的IO操作,BIO)、同步非阻塞NIO)、异步非阻塞AIO)。
  • 同步阻塞:在此种方式下,用户进程在发起一个IO请求以后,必须等待IO请求的返回,只有当IO请求返回以后,用户进程才能继续运行。JAVA传统的IO模型(BIO)属于此种方式。
  • 同步非阻塞:在此种方式下,用户进程发起一个IO请求以后便可以返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。
  • 异步非阻塞:此种方式用户进程发起一个IO请求后,便返回做其他事情,而真正处理IO的应用发起一个IO操作以后,不等待内核IO操作的完成,也可以处理其他事情,等内核完成IO操作以后会通知处理IO的应用,处理IO的应用再通知用户进程。目前JAVA中的AIO就属于异步非阻塞IO。
 
 
Java三种IO的历史
BIO:JDK1.4之前
NIO:JDK1.4推出了java.nio包
AIO:JDK1.7在java.nio.channels包下新增了四个异步通道
  1. AsynchronousSocketChannel
  2. AsynchronousServerSocketChannel
  3. AsynchronousFileChannel
  4. AsynchronousDatagramChannel

从同步阻塞聊到Java三种IO方式的更多相关文章

  1. Java三种IO模型和LinuxIO五种IO模型

    Java: https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/BIO-NIO-AIO.md https://github.co ...

  2. Java三种编译方式

    Java程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理.语言规范.虚拟机规范.本地机器码优化等:了解编译过程有利于了解整个Java运行机制,不仅可以使得我们编写出更优秀的代 ...

  3. java三种调用方式(同步调用/回调/异步调用)

    1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消息或事件的机制 ...

  4. 谈IO中的阻塞和非阻塞,同步和异步及三种IO模型

    什么是同步和异步? 烧水,我们都是通过热水壶来烧水的.在很久之前,科技还没有这么发达的时候,如果我们要烧水,需要把水壶放到火炉上,我们通过观察水壶内的水的沸腾程度来判断水有没有烧开.随着科技的发展,现 ...

  5. 【重学Java】多线程基础(三种创建方式,线程安全,生产者消费者)

    实现多线程 简单了解多线程[理解] 是指从软件或者硬件上实现多个线程并发执行的技术. 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能. 并发和并行[理解] 并行:在同一时刻, ...

  6. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

  7. java代码中init method和destroy method的三种使用方式

    在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等. ...

  8. Java中List集合的三种遍历方式(全网最详)

    List集合在Java日常开发中是必不可少的,只要懂得运用各种各样的方法就可以大大提高我们开发的效率,适当活用各种方法才会使我们开发事半功倍. 我总结了三种List集合的遍历方式,下面一一来介绍. 首 ...

  9. Java连接Oracle数据库的三种连接方式

    背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...

随机推荐

  1. [AH/HNOI2017]礼物

    \[推推公式,即求\Sigma^{n}_{i=1} (x_{i+k}-y_i+c)^2最小,c范围为[-m, m]\] \[拆开,就是\Sigma x_i^2 + \Sigma y_i^2 + n * ...

  2. js去重合并

    1.去重 for(var q = 0;q<jsonArr.length;q++){   for(var e=0;e<jsonArr[q].data.length;e++){   var m ...

  3. Python可视化库-Matplotlib使用总结

    在做完数据分析后,有时候需要将分析结果一目了然地展示出来,此时便离不开Python可视化工具,Matplotlib是Python中的一个2D绘图工具,是另外一个绘图工具seaborn的基础包 先总结下 ...

  4. 【noip模拟】tree

    000 ms        Memory Limit: 128 MB [吐槽] 点分治点分治点分治 嗯..场上思考树状数组的时候好像傻掉了..反正就是挂了就是了.. [题解] 首先如果没有环的话就是一 ...

  5. css学习の第二弹—文字格式化排版

    1.css格式化排版 >>字体设计: etc:body{font-family:"Microsoft Yahei";} >>字号,颜色: etc:body{ ...

  6. git pull error

    在图形界面中,执行拉取操作时,出现下面的错误. You asked to pull from the remote 'origin', but did not specifya branch. Bec ...

  7. mysql 数据库基本命令语句

    mysql mariadb 客户端连接 mysql -uroot -p; 客户端退出exit 或 \q 显示所有数据库show databases;show schemas; 创建数据库create ...

  8. 一名Java架构师分享自己的从业心得,从码农到架构师我用了八年

    工作了挺久,发现有个挺有意思的现象,从程序员.高级程序员,到现在挂着架构师.专家之类的头衔,伴随着技术和能力的提高,想不明白的事情反而越来越多了. 这些疑问有些来自于跟小伙伴的交流,有些是我的自问自答 ...

  9. 1-2 Spring 的基本使用

    1.Spring容器的配置文件applicationContext.xml的引入 名称可以自己定义 <?xml version="1.0" encoding="UT ...

  10. 复习ACCESS注入

    0x00前言:在学校看完了ACCESS注入.但当时并没有电脑,所以做好了笔记 回到家自己搭建了一个有ACCESS注入的站进行练习,虽然这可能没有什么用处 毕竟现在大多的网站都有waf或安全狗.而且AC ...