阻塞非阻塞和同步异步的区分 参考一些书籍

编程中一直对这两个概念不是很理解,在网上搜了很多资料大概描述的其实都很模糊,有时候还自相矛盾,很容易搞混,这里说一下我对这两个概念的理解。
首先看一下相关技术书籍对这两个概念的描述,下面分别是摘自《深入理解Java核心技术》和《Java并发程序设计中的》的内容。
摘自《深入理解Java核心技术》14.2:

当I/O操作发生时,一定是有两方参与的,分别是调用方和被调用方。阻塞和非阻塞描述的是调用方,同步和异步描述的是被调用方。
例如A调用B:
1.如果是阻塞,那么A在发出调用命令后,要一直等待B返回结果。
2.如果是非阻塞,那么A在发出调用命令后,不需要等待,可以去做自己的事情。
3.如果是同步,那么B在收到A的调用命令后,会立即执行要做的事,A的本次调用可以得到结果
4.如果是异步,那么B在收到A的调用命令后,不保证会立即执行要做的事,但是保证会做,B在做好了之后会通知A。A的本次调用得不到·结果,但是B执行完成要做的事之后会通知A。
因为同步/异步与阻塞/非阻塞描述的对象不同,所以这二者之间是没有必然联系的。也就是说,同步不一定阻塞,异步也不一定非阻塞。
只不过通常很少存在异步且阻塞的场景,所以很多人误以为同步一定是非阻塞的、异步一点事非阻塞的。

摘自《Java高并发程序设计》1.2:

同步和异步通常用来形容一次方法的调用。同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而异步方法通常会在另外一个线程中”真实”地执行。整个过程,不会阻碍调用者的工作。对于调用者来说,异步调用似乎是一瞬间就完成的。如果异步调用需要返回结果,那么当这个异步调用真实完成时,则会通知调用者。
阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其他所有需要这个资源的线程就必须在这个临界区中进行等待。等待会导致线程挂起,这种情况就是阻塞。此时,如果占用资源的线程一直不愿意释放资源,那么其他所有阻塞在这个临界区上的线程都不能工作。 非阻塞的意思与之相反,它强调没有一个线程可以妨碍其他线程执行。所有的线程都会尝试不断前向执行。

两本书籍的描述切入点不一样,乍一看两个书籍描述的可能还有点冲突,反而让人更迷糊。
在我看来 阻塞和非阻塞必然是线程或进程相关的,阻塞指的是如果线程无法立即获取到资源是是否需要暂停线程等待资源准备完成,非阻塞则与之相反,即我不会等待我先去干别的事情,等到资源准备好了再通知线程进行处理。
同步即所有的代码都是按顺序执行的,可以理解为这个事情不干完了我就不干别的事情。异步则不可预测顺序的,异步调用必须伴随着通知,可以理解为等到取值完成后我再进行后续的操作,我先去干别的事情。

同步异步和阻塞非阻塞搭配就会出现如下四种组合:

  1. 同步阻塞,如果不能立即获取数据,则线程阻塞等待数据返回。因为程序阻塞了,需要有其他程序将程序唤醒(这里很重要),如java类FileInputStream的readBytes操作。
  2. 同步非阻塞,如果不能立即获取数据,则循环检查数据是否完成。这里不需要其他线程参与唤醒操作。比如java类AtomicInteger的自增操作,如果不能加1就循环执行。
  3. 异步非阻塞,如果不能立即获取数据,则立即返回执行其他操作。等到数据返回了,接收到通知后再进行后续的处理工作(这里后续的处理操作是别的线程去做了,因为当前线程可能已经退出了)。
  4. 异步阻塞,这应该是一个并不存在的组合,异步和阻塞是互斥的。既然都可以异步执行,你还阻塞干什么呢,执行完成之后再通知你不就好了吗,异步的目的不就是无法立即获取数据让线程去干别的事情吗,如果没有别的事情可做就同步阻塞等待就可以了

总结:
如果一个程序说他是异步的,那他肯定非阻塞的,因为并不存在异步阻塞。开启异步的目的就是不想让当前线程阻塞,让他去干其他事情。就是你需要获取一个资源或发出一个通知,但是你并不能立即获取这个资源或者知道通知是否发送成功,这个时候你就需要线程去干别的事( 这里的别的事指不依赖前面调用返回结果的代码)。等结果出来了再对结果进行处理,如对资源解析或者重新发送消息。

Original: https://www.cnblogs.com/soker/p/16440265.html
Author: 大兴神
Title: 阻塞非阻塞和同步异步的区分 参考一些书籍

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/575530/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Mybatis完整版详解

    一、简介 1.什么是MyBatis MyBatis 是一款优秀的持久层框架 它支持自定义 SQL、存储过程以及高级映射。 MyBatis 免除了几乎所有的 JDBC 代码以及设置参…

    Java 2023年6月14日
    054
  • Elastic APM安装

    安装前准备: 安装之前事先安装好elasticsearch和kibana。 下载安装包: apm-server-7.0.0-linux-x86_64.tar.gz (服务端包)el…

    Java 2023年6月6日
    0103
  • MAC电脑安装openJdk

    一、安全brew软件 [1]安全命令地址:https://brew.sh/index_zh-cn /bin/bash -c "$(curl -fsSL https://r…

    Java 2023年5月30日
    063
  • Spring与Web环境集成

    Spring与Web环境集成 1. ApplicationContext应用上下文获取方式 应用上下文对象是通过 new ClassPathXmlApplicationContex…

    Java 2023年6月5日
    095
  • 【转载】分享下多年积累的对JAVA程序员成长之路的总结

    注:该文是从百度贴吧转载过来,之前看到觉得写得还不错,对Java开发学习者来说很有意义的,可以看看。 我也搞了几年JAVA 了,由于一向懒惰,没有成为大牛,只是一普通程序猿,不爱玩…

    Java 2023年6月7日
    075
  • 不重启tomcat,清空catalina.out的几种方式

    相信小伙伴们使用tomcat容器部署项目时,都会遇到这个问题 尤其是刚上线日志级别一般启动为DEBUG级别时,catalina.out文件过一会就会特别特别大,特别占我们服务器上的…

    Java 2023年6月16日
    089
  • 关于非对称加密的一点解说

    非对称加密定义: 非对称加密算法又称 现代加密算&#x6CD5…

    Java 2023年6月16日
    098
  • 2022-7-7学习日记

    马士兵 String、StringBuffer SttingBuiler String 是final修饰的,不可变的,每次操作都会产生新的String对象 StringBuffer…

    Java 2023年6月6日
    057
  • 设计模式之策略模式

    策略模式属于行为型模式,是使用最多的设计模式之一;其作用是针对一组算法,将每一个算法封装到具体共同接口的独立的类种,从而使得他们可以相互转化。策略模式使得算法可以在不影响到客户端得…

    Java 2023年6月5日
    078
  • Spring5.0源码学习系列之事务管理概述

    Spring源码学习系列博客专栏:链接 Spring5.0源码学习系列之事务管理概述(十一),在学习事务管理的源码之前,需要对事务的基本理论比较熟悉,所以本章节会对事务管理的基本理…

    Java 2023年5月30日
    062
  • Java8新特性Optional

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月7日
    067
  • JDK1.8 StampedLock: 解决ReentrantReadWriteLock在读多写少情况下,写线程饥饿问题

    ReentrantReadWriteLock 在沒有任何读写锁时,才可以取得写入锁,这可用于实现了悲观读取(Pessimistic Reading), 即如果执行中进行读取时,经常…

    Java 2023年5月29日
    089
  • Spring Boot 实现各种参数校验(附项目源码)

    本文会详细介绍 Spring Validation各种场景下的最佳实践及其实现原理,死磕到底! 项目源码:spring-validation 一、简单使用 Java API规范(J…

    Java 2023年5月30日
    066
  • easyUI 添加排序到datagrid

    @author YHC 这个示例展示如何排序datagrid通过点击列表头. 查看 Demo 在datagrid的所有columns 可以通过点击列表头排序,你可以定义哪行可以排序…

    Java 2023年5月29日
    077
  • jvm垃圾回收的过程

    垃圾回收的过程分为两步: 1.判断对象是否死亡 (1)引用计数器法: ①每当有一个对象引用是,计数器加一,当计数器为0是对象死亡 ②缺点:无法解决循环引用的问题,假设A引用B,B引…

    Java 2023年6月6日
    081
  • Aviator——轻量级Java表达式求值引擎

    简介 Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什么还需要Avaitor…

    Java 2023年5月29日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球