zoukankan      html  css  js  c++  java
  • 从同步阻塞聊到Java三种IO方式

    本文总结自
     
     
    快速理解
    首先,我们要先对这几个概念有一个直观的理解,对于初学者来说,你可以这样看待这几个概念:
    • 阻塞非阻塞 指的是在客户端
      • 阻塞:意味着 客户端提出一个请求以后,在得到回应之前,只能等待
      • 非阻塞:意味着 客户端提出一个请求以后,在得到回应之前,客户端还可以做其他事情
    • 同步异步 指的是服务器端
      • 同步:意味着 服务器接受一个请求后,在返回结果以前不能做其他的事情
      • 异步:意味着 服务器接受一个请求后,尽管还没有返回结果,但是可以做其他的事情
    这样的理解其实是过于以偏概全的,因为这只是消息通知场景中的解释,但是通过代入客户端,服务器端更加方便初学者理解,因此在这里,暂且先这样解释。
     
     
    举个例子
    小明领着女朋友去超市购物,买了很多东西,当他走到收银员那里结账的时候,小明(客户端)发出了要求结账的讯息(请求),收银员(服务器)会对他这一要求进行处理。此时有可能产生多种场景
    • 小明傻傻地等着收银员用计算器算出所有物品的总价,并准备付款。(同步阻塞小明在请求响应之前,一直在等待;收银员没有做别的事情,一直在处理小明的请求)
    • 小明觉得自己太傻了,于是一边和女朋友聊天,一边催促收银员快点计算出总价。(同步非阻塞小明在请求响应之前,做了其他的事情;收银员一直在处理小明的请求)
    • 小明傻傻地等着收银员的总价结果,收银员却把计算的工作交给计算机之后就去拿袋子帮忙装东西,直到计算机上出现了总价结果,收银员才继续回来完成收款工作。(异步阻塞小明在请求响应之前,一直在等待;收银员在处理小明请求的过程中,处理了其他的事情)
    • 小明觉得自己太傻了,于是一边和女朋友聊天,一边催出收银员快点计算出总价,而收银员却把计算的工作交给计算机之后就去拿袋子帮忙装东西,直到计算机上出现了总价结果,收银员才继续回来完成收款工作。(异步非阻塞小明在请求响应之前做了其他的事情;收银员也在处理请求的过程中,处理了其他的事情)
    在这个例子中:
    • 阻塞,非阻塞,指的是小明是否在等待处理结果的过程中去做了其他的事情。
    • 同步,异步,指的是收银员是否在处理收款这一请求的过程中去做了其他的事情,这也导致了收款的结果是当时告诉了小明,还是之后又进行了额外的通知。
     
    再来个例子
    老张爱喝茶,废话不说,煮开水。
    出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
    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
  • 相关阅读:
    mysql 常用命令
    MAC 升级到10.10(OS X Yosemite)下apache+php的配置问题
    php 第1讲 html介绍 html运行原理①
    php 开山篇
    Sublime Text 2
    java 抽象类和接口整理
    petri 网理论与研究(第一节140915)
    程序员应该读的书
    python logging模块小记
    常见设计模式,单例模式(双重检测锁方式)示例
  • 原文地址:https://www.cnblogs.com/noodleprince/p/8647670.html
Copyright © 2011-2022 走看看