简述JAVA同步、异步、阻塞和非阻塞之间的区别

同步和异步,阻塞和非阻塞是大家经常会听到的概念,但是它们是从不同维度来描述一件事情,常常很容易混为一谈。

1. 同步和异步

同步和异步描述的是消息通信的机制。

同步

当一个request发送出去以后,会得到一个response,这整个过程就是一个同步调用的过程。哪怕response为空,或者response的返回特别快,但是针对这一次请求而言就是一个同步的调用。

异步

当一个request发送出去以后,没有得到想要的response,而是通过后面的callback、状态或者通知的方式获得结果。可以这么理解,对于异步请求分两步:

1)调用方发送request没有返回对应的response(可能是一个空的response);

2)服务提供方将response处理完成以后通过callback的方式通知调用方。

对于1)而言是同步操作(调用方请求服务方),对于2)而言也是同步操作(服务方回掉调用方)。从请求的目的(调用方发送一个request,希望获得对应的response)来看,这两个步骤拆分开来没有任何意义,需要结合起来看,而这整个过程就是一次异步请求。异步请求有一个最典型的特点:需要callback、状态或者通知的方式来告知调用方结果。

2. 阻塞和非阻塞

阻塞和非阻塞描述的是程序在等待调用结果(消息,返回值)时的状态。

阻塞

阻塞调用是指调用方发出request的线程因为某种原因(如:等待系统资源)被服务方挂起,当服务方得到response后就唤醒挂起线程,并将response返回给调用方。

非阻塞

非阻塞调用是指调用方发出request的线程在没有等到结果时不会被挂起,直到得到response后才返回。

阻塞和非阻塞最大的区别就是看调用方线程是否会被挂起。

3. 同步、异步、阻塞和非阻塞IO

同步阻塞IO

针对Sender而言,请求发送出去以后,一直等到Receiver有结果了才返回,这是同步。在Sender获取结果的期间一直被block住了,也就是在此期间Sender不能处理其它事情,这是阻塞。

异步阻塞IO

针对Sender而言,请求发送出去以后,立刻返回,然后再等待Receiver的callback,最后再次请求获取response,这整个过程是异步。在Sender等待Receiver的callback期间一直被block住了,也就是在此期间Sender不能处理其它事情,这是阻塞。

同步非阻塞IO

针对Sender而言,请求发送出去以后,立刻返回,然后再不停的发送请求,直到Receiver处理好结果后,最后一次发请求给Receiver才获得response。Sender一直在主动轮询,每一个请求都是同步的,整个过程也是同步的。在Sender等待Receiver的response期间一直是可以处理其它事情的(比如:可以发送请求询问结果),这是非阻塞。

异步非阻塞IO

针对Sender而言,请求发送出去以后,立刻返回,然后再等待Receiver的callback,最后再次请求获取response,这整个过程是异步。在Sender等待Receiver的callback期间一直是可以处理其它事情的,这是非阻塞。

总结

  • 同步和异步就看调用方是否需要通过callback、通知或者状态来获取结果
  • 阻塞和非阻塞就看调用方在发送请求后是否block住了

以上就是简述JAVA同步、异步、阻塞和非阻塞之间的区别的详细内容,更多关于JAVA同步、异步、阻塞和非阻塞的区别的资料请关注我们其它相关文章!

时间: 2020-07-31

java 同步、异步、阻塞和非阻塞分析

java 同步.异步.阻塞和非阻塞分析 概要: 正常情况下,我们的程序以同步非阻塞的方式在运行.但是我们的程序总会出现一些耗时操作,比如复杂的计算(找出1到10亿之间的素数)和程序本身无法控制的操作(IO操作.网络请求).包含这些耗时操作的方法我们可以把它称为阻塞方法,包含这些耗时操作的任务我们可以把它称为阻塞任务.阻塞与非阻塞是以是否耗时来定义的. 如果程序中存在大量阻塞操作,就会影响程序性能.但是阻塞的存在是客观事实,我们的程序是无法改变它的,一个网络请求需要3秒才能响应,我们不可能让它1毫

java 中同步、异步、阻塞和非阻塞区别详解

java 中同步.异步.阻塞和非阻塞区别详解 简单点说: 阻塞就是干不完不准回来,一直处于等待中,直到事情处理完成才返回: 非阻塞就是你先干,我先看看有其他事没有,一发现事情被卡住,马上报告领导. 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系统内部send做的工作其实只是把数据传输(Copy)到TCP/IP协议栈的输出缓冲区,它执行成功并不代表数据已经成功的发送出去了,如果TCP/IP协议栈没有足够的可用缓冲区来保存你Copy过来的数据的话

Java中String、StringBuffer、StringBuilder的区别详解

java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可变 String类中使用字符数组保存字符串,如下就是,因为有"final"修饰符,所以可以知道string对象是不可变的. private final char value[]; StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在A

Java中Object.equals和String.equals的区别详解

前言 Java中的堆和常量池的区别是什么呢?Object.equals与String.equals的区别呢?下面让我妈通过一个小示例让你明白它- 1.基础知识 Java的存储空间:寄存器.栈.堆.静态存储区.常量存储区(常量池).其他存储位置. 此处重点介绍堆和常量存储区: 堆:存储new的对象; 常量池:用来存储final static.String的常量. 2.Object.equals与String.equals的区别 Object.equals(==):比较内存地址: String.eq

Java中Hashtable类与HashMap类的区别详解

Hashtable类 Hashtable继承Map接口,实现一个key-value映射的哈希表.任何非空(non-null)的对象都可作为key或者value. 添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数. Hashtable通过initial capacity和load factor两个参数调整性能.通常缺省的load factor 0.75较好地实现了时间和空间的均衡.增大load factor可以节省空间但相应的查找时间将增大,

java中timer的schedule和scheduleAtFixedRate方法区别详解

timer的schedule和scheduleAtFixedRate方法一般情况下是没什么区别的,只在某个情况出现时会有区别--当前任务没有来得及完成下次任务又交到手上. 我们来举个例子: 暑假到了老师给schedule和scheduleAtFixedRate两个同学布置作业. 老师要求学生暑假每天写2页,30天后完成作业. 这两个学生每天按时完成作业,直到第10天,出了意外,两个学生出去旅游花了5天时间,这5天时间里两个人都没有做作业.任务被拖延了. 这时候两个学生采取的策略就不同了: sch

基于Java中最常用的集合类框架之HashMap(详解)

一.HashMap的概述 HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构. HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射操作.存储的是对的映射,允许多个null值和一个null键.但此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 除了HashMap是非同步以及允许使用null外,HashMap 类与 Hashtable大致相同. 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性

Java中的引用和动态代理的实现详解

我们知道,动态代理(这里指JDK的动态代理)与静态代理的区别在于,其真实的代理类是动态生成的.但具体是怎么生成,生成的代理类包含了哪些内容,以什么形式存在,它为什么一定要以接口为基础? 如果去看动态代理的源代码(java.lang.reflect.Proxy),会发现其原理很简单(真正二进制类文件的生成是在本地方法中完成,源代码中没有),但其中用到了一个缓冲类java.lang.reflect.WeakCache<ClassLoader,Class<?>[],Class<?>

java 中mongodb的各种操作查询的实例详解

java 中mongodb的各种操作查询的实例详解 一. 常用查询: 1. 查询一条数据:(多用于保存时判断db中是否已有当前数据,这里 is  精确匹配,模糊匹配 使用regex...) public PageUrl getByUrl(String url) { return findOne(new Query(Criteria.where("url").is(url)),PageUrl.class); } 2. 查询多条数据:linkUrl.id 属于分级查询 public Lis

java中 Set与Map排序输出到Writer详解及实例

 java中 Set与Map排序输出到Writer详解及实例 一般来说java.util.Set,java.util.Map输出的内容的顺序并不是按key的顺序排列的,但是java.util.TreeMap,java.util.TreeSet的实现却可以让Map/Set中元素内容以key的顺序排序,所以利用这个特性,可以将Map/Set转为TreeMap,TreeSet然后实现排序输出. 以下是实现的代码片段: /** * 对{@link Map}中元素以key排序后,每行以{key}={val

java 中基本算法之希尔排序的实例详解

java 中基本算法之希尔排序的实例详解 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出而得名. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差

java 中枚举类enum的values()方法的详解

java 中枚举类enum的values()方法的详解 前言: 关于枚举,相信使用的已经很普遍了,现在主要写的是枚举中的一个特殊方法,values(), 为什么说特殊呢,因为在Enum 的 API 文档中也找不到这个方法.接下来就看看具体的使用. 理论上此方法可以将枚举类转变为一个枚举类型的数组,因为枚举中没有下标,我们没有办法通过下标来快速找到需要的枚举类,这时候,转变为数组之后,我们就可以通过数组的下标,来找到我们需要的枚举类.接下来就展示代码了. 首先是我们自己的枚举类. public e