自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Ssssongsmith 天璇星

改变自己从现在开始

  • 博客(158)
  • 收藏
  • 关注

原创 分布式事务:Alibaba Seata 如何实现分布式事务

分布式事务的解决方案:为什么会产生分布式事务。举个例子,某线上商城会员在购买商品的同时产生相应的消费积分,消费积分在下一次购物时可以抵用现金。这个业务的逻辑如果放在以前的单点应用是很简单的,如下所示开启数据库事务创建订单会员积分增加商品库存减少提交数据库事务在这个过程中,因为程序操作的是单点数据库,所以在一个数据库事务中便可完成所有操作,利用数据库事务自带的原子性保证了所有数据要么全部处理成功,要么全部回滚撤销。但是放在以微服务为代表的分布式架构下问题就没那么简单了,看一下示意图。分布式架

2021-04-10 10:42:37 377

原创 Spring Cloud Stream 框架对消息处理机制/事件驱动架构

Spring Cloud 专门提供了一个 Spring Cloud Stream 框架来实现事件驱动架构,并完成与主流消息中间件的集成。同时,Spring Cloud Stream 背后也整合了 Spring 家族中的消息处理和消息总线方面的几个框架,可以说是 Spring Cloud 中整合程度最高的一个开发框架。现在的需求是这样的:系统中的某个服务会因为用户操作或内部行为发布一个事件,该服务知道这个事件在将来的某一个时间点会被其他服务所消费,但是并不知道这个服务具体是谁、也不关心什么时候被消费。同

2021-03-12 08:30:17 535

原创 分布式事务解决方案/思路/方向 ! ! !

分布式事务是分布式系统中非常重要的一部分,最典型的例子是银行转账和扣款,A 和 B 的账户信息在不同的服务器上,A 给 B 转账 100 元,要完成这个操作,需要两个步骤,从 A 的账户上扣款,以及在 B 的账户上增加金额,两个步骤必须全部执行成功;否则如果有一个失败,那么另一个操作也不能执行。那么像这种转账扣款的例子,在业务中如何保证一致性,有哪些解决方案、思路/方向呢?分布式事务是什么 ?顾名思义,分布式事务关注的是分布式场景下如何处理事务,是指事务的参与者、支持事务操作的服务器、存储等资源分别位

2021-03-09 22:43:24 194

原创 Spring Boot 事务传播机制级别/类型/行为、嵌套事务、事务隔离机制

首先呢? 事务的传播行为是针对 ‘嵌套事务而言’ 疑问所在?先说 Spring 传播机制级别/类型、~七种:事务传播机制/行为 ~ ~五类:事务隔离级别 - Required(adj. 必需的)|默认 -Default(v. 不履行)默认 - Requires_new(vt. 需要New) -Read_Uncommitted(读未提交) - Mandatory(adj. 强制的) -Read_Committed(读已提交) - S

2021-03-05 23:45:00 1840 5

原创 MyBatis 使用了哪些设计模式?在源码中是如何体现的?

MyBatis 的前身是 IBatis,IBatis 是由 Internet 和 Abatis 组合而成,其目的是想当做互联网的篱笆墙,围绕着数据库提供持久化服务的一个框架,2010 年正式改名为 MyBatis。它是一款优秀的持久层框架,支持自定义 SQL、存储过程及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,还可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Ordinary Java Object,普通 Java

2021-03-21 14:22:06 328

原创 分布式事务解决方案中两阶段提交协议对比三阶段协议改进增加协调者/参与者/超时机制......

在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。在关系型数据库中,由于存在事务机制,可以保证每个独立节点上的数据操作满足 ACID。但是,相互独立的节点之间无法准确的知道其他节点中的事务执行情况,所以在分布式的场景下,如果不添加额外的机制,多个节点之间理论上无法达到一致的状态。在分布式事务中,两阶段和三阶段提交是经典的一致性算法,那么两阶段和三阶段提交的具体流程是怎样的,三阶段提交又是如何改进的呢?协调者统一调度在分布式事务的定义中,如果想让分布式部署的多台机器中的数据保

2021-03-14 19:36:21 708

原创 Spring Cloud Stream 的基本架构

接着上篇内容(事件驱动架构的基本原理,以及 Spring 中对消息传递机制的抽象和对应的开发框架)继续说,要想在 SpringHealth 案例系统中添加消息发送和接收的效果有很多种实现方法,完全可以直接使用诸如RocketMQ、RabbitMQ、Kafka 等消息中间件来实现消息传递,考虑不同框架的使用方式以及框架之间存在的功能差异性。而 Spring Cloud Stream ,它在内部整合了多款主流的消息中间件,提供了一个平台型解决方案,从而屏蔽各个消息中间件在技术实现上的差异。Spring C

2021-03-14 07:00:04 458

原创 -日志框架千千万,MyBatis 都能兼容的秘密是什么?

Apache Commons Logging、Log4j、Log4j2、java.util.logging 等是 Java 开发中常用的几款日志框架,这些日志框架来源于不同的开源组织,给用户暴露的接口也有很多不同之处,所以很多开源框架会自己定义一套统一的日志接口,兼容上述第三方日志框架,供上层使用。一般实现的方式是使用适配器模式,将各个第三方日志框架接口转换为框架内部自定义的日志接口。MyBatis 也提供了类似的实现。适配器模式适配器模式主要解决的是由于接口不能兼容而导致类无法使用的问题,这在处理遗

2021-03-04 23:20:30 169

原创 MyBatis 反射工具箱、反射设计思

反射是 Java 世界中非常强大、非常灵活的一种机制。在面向对象的 Java 语言中,我们只能按照 public、private 等关键字的规范去访问一个 Java 对象的属性和方法,但反射机制可以让我们在运行时拿到任何 Java 对象的属性或方法。有人说反射打破了类的封装性,破坏了我们的面向对象思维,我倒不这么认为。我觉得正是由于 Java 的反射机制,解决了很多面向对象无法解决的问题,才受到众多 Java 开源框架的青睐,也出现了有很多惊艳的反射实践,当然,这也包括 MyBatis 中的反射工具箱。

2021-03-03 23:49:54 215

原创 -MyBatis 源码环境搭建及整体架构解析

在上次,我通过一个订单系统的示例,展示了 MyBatis 在实践项目中的基本使用,以帮助你快速上手使用 MyBatis 框架。在这次,我就来带你搭建 MyBatis 源码调试的环境,并为你解析 MyBatis 的源码结构,这些都是在为后面的源码分析做铺垫。MySQL 安装与启动安装并启动一个关系型数据是调试 MyBatis 源码的基础。目前很多互联网公司都将 MySQL 作为首选数据库,所以这里我也就选用 MySQL 数据库来配合调试 MyBatis 源码下载 MySQL首先,从 MySQL 官网

2021-03-02 21:44:25 313 1

原创 -订单系统持久层示例分析,20 分钟带你快速上手 MyBatis

在开始深入分析 MyBatis 核心架构以及具体代码实现之前,我先通过一个示例来帮助你快速了解 MyBatis 中的常见概念以及其基础使用方法。这里我会以一个简易订单系统的持久化层为例进行讲解,整体的讲解逻辑是这样的:首先介绍订单系统 domain 层的设计,了解如何将业务概念抽象成 Java 类;接下来介绍数据库表的设计,同时说明关系型的数据库表与面向对象模型的类之间的映射关系;随后介绍订单系统的 DAO 接口层,DAO 接口层是操作数据的最小化单元,也是读写数据库的地基;最后再简单提供了一个

2021-03-01 22:09:00 261

原创 AQS 的内部原理是什么样的?

AQS 内部原理解析我们对 AQS 进行内部原理解析的话需要抓住重点,因为 AQS 的内部比较复杂,代码很长而且非常不容易读懂,如果我们一上来就一头扎进去读源码,是很难完全掌握它的。所以在本课时中,我们把 AQS 最核心的三个部分作为重点提炼出来,由这三个部分作为切入点,打开 AQS 的大门。是哪三大部分呢?AQS 最核心的三大部分就是状态、队列和期望协作工具类去实现的获取/释放等重要方法。我们就从这三个部分出发,分别展开讲解。state 状态第一个要讲解的是状态 state,如果我们的 AQS 想

2021-02-28 21:41:17 211

原创 常见持久层框架赏析,到底是什么让你选择 MyBatis?

在绝大多数在线应用场景中,数据是存储在关系型数据库中的,当然,有特殊要求的场景中,我们也会将其他持久化存储(如 ElasticSearch、HBase、MongoDB 等)作为辅助存储。但不可否认的是,关系型数据库凭借几十年的发展、生态积累、众多成功的案例,依然是互联网企业的核心存储。作为一个 Java 开发者,几乎天天与关系型数据库打交道,在生产环境中常用的关系型数据库产品有 SQL Server、MySQL、Oracle 等。在使用这些数据库产品的时候,基本上是如下思路:在写 Java 代码的过程中

2021-02-27 23:29:33 1543

原创 -AQS 在 CountDownLatch 等类中的应用原理是什么?

分享内容: AQS 在 CountDownLatch 类中的应用原理,即在 CountDownLatch 中如何利用 AQS 去实现 CountDownLatch 自己的线程协作逻辑的。本课时会包含一定的源码分析。AQS 用法我们先讲一下 AQS 的用法。如果想使用 AQS 来写一个自己的线程协作工具类,通常而言是分为以下三步,这也是 JDK 里利用 AQS 类的主要步骤:第一步,新建一个自己的线程协作工具类,在内部写一个 Sync 类,该 Sync 类继承 AbstractQueuedSynchr

2021-02-26 21:51:00 150

原创 为什么需要 AQS?AQS 的作用和重要性是什么?

AQS 的重要性我们先来介绍一下 AQS(AbstractQueuedSynchronizer)的重要性,来看看 AQS 被用在了哪些类里面。如图所示,AQS 在 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、ThreadPoolExcutor 的 Worker 中都有运用(JDK 1.8),AQS 是这些类的底层原理。而以上这些类,很多都是我们经常使用的类,大部分我们在前面课时中也已经详细介绍过,所以说 JUC 包里很多

2021-02-24 12:56:16 619

原创 -为什么 String 被设计为是不可变的?

String 是不可变的我们先来介绍一下“String 是不可变的”这件事。在 Java 中,字符串是一个常量,我们一旦创建了一个 String 对象,就无法改变它的值,它的内容也就不可能发生变化(不考虑反射这种特殊行为)。举个例子,比如我们给字符串 s 赋值为“lagou”,然后再尝试给它赋一个新值,正如下面这段代码所示:String s = "rinvay";s = "r";看上去好像是改变了字符串的值,但其背后实际上是新建了一个新的字符串“r”,并且把 s 的引用指向这个新创建出来的字符串

2021-02-22 20:04:42 157 3

原创 为什么加了 final 却依然无法拥有“不变性”?

什么是不变性要想回答上面的问题,我们首先得知道什么是不变性(Immutable)。如果对象在被创建之后,其状态就不能修改了,那么它就具备“不变性”。我们举个例子,比如下面这个 Person 类:public class Person { final int id = 1; final int age = 18;}如果我们创建一个 person 对象,那么里面的属性会有两个,即 id 和 age,并且由于它们都是被 final 修饰的,所以一旦这个 person 对象被创建好,那么

2021-02-21 16:04:35 131 3

原创 -final 的三种用法是什么?

final 的作用final 是 Java 中的一个关键字,简而言之,final 的作用意味着“这是无法改变的”。不过由于 final 关键字一共有三种用法,它可以用来修饰变量、方法或者类,而且在修饰不同的地方时,效果、含义和侧重点也会有所不同,所以我们需要把这三种情况分开介绍。我们先来看一下 final 修饰变量的情况。final 修饰变量作用关键字 final 修饰变量的作用是很明确的,那就是意味着这个变量一旦被赋值就不能被修改了,也就是说只能被赋值一次,直到天涯海角也不会“变心”。如果我们尝

2021-02-20 22:14:57 364 2

原创 70-有哪些解决死锁问题的策略?

线上发生死锁应该怎么办如果线上环境发生了死锁,那么其实不良后果就已经造成了,修复死锁的最好时机在于“防患于未然”,而不是事后补救。就好比发生火灾时,一旦着了大火,想要不造成损失去扑灭几乎已经不可能了。死锁也是一样的,如果线上发生死锁问题,为了尽快减小损失,最好的办法是保存 JVM 信息、日志等“案发现场”的数据,然后立刻重启服务,来尝试修复死锁。为什么说重启服务能解决这个问题呢?因为发生死锁往往要有很多前提条件的,并且当并发度足够高的时候才有可能会发生死锁,所以重启后再次立刻发生死锁的几率并不是很大,当我

2021-02-19 14:58:37 485 2

原创 -你知道什么是 CAS 吗?

CAS 简介CAS 其实是我们面试中的常客,因为它是原子类的底层原理,同时也是乐观锁的原理,所以当你去面试的时候,经常会遇到这样的问题“你知道哪些类型的锁”?你可能会回答“悲观锁和乐观锁”,那么下一个问题很有可能是问乐观锁的原理,也就是和 CAS 相关的问题,当然也有可能会继续深入问你 CAS 的应用场景或者是缺点等问题。首先我们来看一下 CAS 是什么,它的英文全称是 Compare-And-Swap,中文叫做“比较并交换”,它是一种思想、一种算法。在多线程的情况下,各个代码的执行顺序是不能确定的,

2021-02-18 10:38:11 3181 1

原创 69-如何用命令行和代码定位死锁?

在此之前,我们介绍了什么是死锁,以及死锁发生的必要条件。当然,即便我们很小心地编写代码,也必不可免地依然有可能会发生死锁,一旦死锁发生,第一步要做的就是把它给找到,因为在找到并定位到死锁之后,才能有接下来的补救措施,比如解除死锁、解除死锁之后恢复、对代码进行优化等;若找不到死锁的话,后面的步骤就无从谈起了。下面就来看一下是如何用命令行的方式找到死锁的。命令:jstack这个命令叫作 jstack,它能看到我们 Java 线程的一些相关信息。如果是比较明显的死锁关系,那么这个工具就可以直接检测出来;如果

2021-02-17 13:12:08 269 1

原创 68-发生死锁必须满足哪 4 个条件?

发生死锁的 4 个必要条件要想发生死锁有 4 个缺一不可的必要条件,我们一个个来看:第 1 个叫互斥条件,它的意思是每个资源每次只能被一个线程(或进程,下同)使用,为什么资源不能同时被多个线程或进程使用呢?这是因为如果每个人都可以拿到想要的资源,那就不需要等待,所以是不可能发生死锁的。第 2 个是请求与保持条件,它是指当一个线程因请求资源而阻塞时,则需对已获得的资源保持不放。如果在请求资源时阻塞了,并且会自动释放手中资源(例如锁)的话,那别人自然就能拿到我刚才释放的资源,也就不会形成死锁。

2021-02-16 16:10:58 113 1

原创 67-如何写一个必然死锁的例子?

死锁是什么?有什么危害?什么是死锁发生在并发中首先你要知道,死锁一定发生在并发场景中。我们为了保证线程安全,有时会给程序使用各种能保证并发安全的工具,尤其是锁,但是如果在使用过程中处理不得当,就有可能会导致发生死锁的情况。互不相让死锁是一种状态,当两个(或多个)线程(或进程)相互持有对方所需要的资源,却又都不主动释放自己手中所持有的资源,导致大家都获取不到自己想要的资源,所有相关的线程(或进程)都无法继续往下执行,在未改变这种状态之前都不能向前推进,我们就把这种状态称为死锁状态,认为它们发生了死锁

2021-02-15 10:41:35 199

原创 66-CAS 有什么缺点?

CAS 是有很多优点的,比如可以避免加互斥锁,可以提高程序的运行效率,但是同样 CAS 也有非常明显的缺点。所以我们在使用 CAS 的时候应该同时考虑到它的优缺点,合理地进行技术选型。下面我们就来看一下 CAS 有哪几个主要的缺点。ABA 问题首先,CAS 最大的缺点就是 ABA 问题。决定 CAS 是否进行 swap 的判断标准是“当前的值和预期的值是否一致”,如果一致,就认为在此期间这个数值没有发生过变动,这在大多数情况下是没有问题的。但是在有的业务场景下,我们想确切知道从上一次看到这个值以来

2021-02-12 19:44:42 1979 4

原创 65- CAS 和乐观锁的关系,什么时候会用到 CAS?

并发容器Doug Lea 大神在 JUC 包中大量使用了 CAS 技术,该技术既能保证安全性,又不需要使用互斥锁,能大大提升工具类的性能。下面我将通过两个例子来展示 CAS 在并发容器中的使用情况。案例一:ConcurrentHashMap先来看看并发容器 ConcurrentHashMap 的例子,我们截取部分 putVal 方法的代码,如下所示:final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null |

2021-02-12 00:01:09 193 1

原创 63-单例模式的双重检查锁模式为什么必须加 volatile?

什么是单例模式单例模式指的是,保证一个类只有一个实例,并且提供一个可以全局访问的入口。为什么需要使用单例模式那么我们为什么需要单例呢?其中**一个理由,那就是为了节省内存、节省计算。**因为在很多情况下,我们只需要一个实例就够了,如果出现更多的实例,反而纯属浪费。下面我们举一个例子来说明这个情况,以一个初始化比较耗时的类来说,代码如下所示:public class ExpensiveResource { public ExpensiveResource() { field1

2021-02-10 19:19:00 393 10

原创 62-volatile 的作用是什么?与 synchronized 有什么异同?

volatile 是什么首先我们就来介绍一下 volatile,它是 Java 中的一个关键字,是一种同步机制。当某个变量是共享变量,且这个变量是被 volatile 修饰的,那么在修改了这个变量的值之后,再读取该变量的值时,可以保证获取到的是修改后的最新的值,而不是过期的值。相比于 synchronized 或者 Lock,volatile 是更轻量的,因为使用 volatile 不会发生上下文切换等开销很大的情况,不会让线程阻塞。但正是由于它的开销相对比较小,所以它的效果,也就是能力,相对也小一些。

2021-02-08 13:34:36 159 3

原创 61-什么是 happens-before 规则?

什么是 happens-before 关系Happens-before 关系是用来描述和可见性相关问题的:如果第一个操作 happens-before 第二个操作(也可以描述为,第一个操作和第二个操作之间满足 happens-before 关系),那么我们就说第一个操作对于第二个操作一定是可见的,也就是第二个操作在执行时就一定能保证看见第一个操作执行的结果。不具备 happens-before 关系的例子我们先来举一个不具备 happens-before 关系的例子,从宏观上进一步理解 happens

2021-02-06 22:13:59 354

原创 60-主内存和工作内存的关系?

CPU 有多级缓存,导致读的数据过期由于 CPU 的处理速度很快,相比之下,内存的速度就显得很慢,所以为了提高 CPU 的整体运行效率,减少空闲时间,在 CPU 和内存之间会有 cache 层,也就是缓存层的存在。虽然缓存的容量比内存小,但是缓存的速度却比内存的速度要快得多,其中 L1 缓存的速度仅次于寄存器的速度。结构示意图如下所示:在图中,从下往上分别是内存,L3 缓存、L2 缓存、L1 缓存,寄存器,然后最上层是 CPU 的 4个核心。从内存,到 L3 缓存,再到 L2 和 L1 缓存,它们距离

2021-02-05 20:22:27 234

原创 59-什么是“内存可见性”问题?

我们先从两个案例来入手,看一看什么是可见性问题。案例一我们来看看下面的代码,有一个变量 x,它是 int 类型的,如下所示:public class Visibility { int x = 0; public void write() { x = 1; } public void read() { int y = x; }}这是一段很简单的代码,类中有两个方法:write 方法,作用是给 x 赋值,代码中,把 x 赋值

2021-02-05 09:03:55 686 3

原创 58-Java 中的原子操作有哪些注意事项?

什么是原子性和原子操作在编程中,具备原子性的操作被称为原子操作。原子操作是指一系列的操作,要么全部发生,要么全部不发生,不会出现执行一半就终止的情况。比如转账行为就是一个原子操作,该过程包含扣除余额、银行系统生成转账记录、对方余额增加等一系列操作。虽然整个过程包含多个操作,但由于这一系列操作被合并成一个原子操作,所以它们要么全部执行成功,要么全部不执行,不会出现执行一半的情况。比如我的余额已经扣除,但是对方的余额却不增加,这种情况是不会出现的,所以说转账行为是具备原子性的。而具有原子性的原子操作,天然具

2021-02-04 15:39:26 157 7

原创 57-什么是指令重排序?为什么要重排序?

什么是重排序假设我们写了一个 Java 程序,包含一系列的语句,我们会默认期望这些语句的实际运行顺序和写的代码顺序一致。但实际上,编译器、JVM 或者 CPU 都有可能出于优化等目的,对于实际指令执行的顺序进行调整,这就是重排序。重排序的好处:提高处理速度你可能感到很困惑,为什么要重排序?这样做有什么好处呢?我们来举一个具体的例子。图中左侧是 3 行 Java 代码,右侧是这 3 行代码可能被转化成的指令。可以看出 a = 100 对应的是 Load a、Set to 100、Store a,意

2021-02-02 18:31:02 336 3

原创 56-什么是 Java 内存模型?

了解 Java 并发的底层原理,那么 Java 内存模型的知识非常重要,同时也是一个分水岭,可以区分出我们是仅停留在如何使用并发工具,还是能更进一步,知其所以然。容易混淆:JVM 内存结构 VS Java 内存模型Java 作为一种面向对象的语言,有很多概念,从名称上看起来比较相似,比如 JVM 内存结构、Java 内存模型,这是两个截然不同的概念,但是很容易混淆。网络上也有不少讲 Java 内存模型的文章,其实写的是 JVM 内存结构。所以我们就先从整体上概括一下这两者的主要作用:JVM 内存

2021-02-01 21:21:59 161

原创 55-Condition、object.wait() 和 notify() 的关系?

Condition 这个接口,来看看它的作用、如何使用,以及需要注意的点有哪些。Condition接口作用我们假设线程 1 需要等待某些条件满足后,才能继续运行,这个条件会根据业务场景不同,有不同的可能性,比如等待某个时间点到达或者等待某些任务处理完毕。在这种情况下,我们就可以执行 Condition 的 await 方法,一旦执行了该方法,这个线程就会进入 WAITING 状态。通常会有另外一个线程,我们把它称作线程 2,它去达成对应的条件,直到这个条件达成之后,那么,线程 2 调用 Condit

2021-01-31 22:45:36 192 4

原创 54-CyclicBarrier 和 CountdownLatch 有什么异同?

CyclicBarrier作用CyclicBarrier 和 CountDownLatch 确实有一定的相似性,它们都能阻塞一个或者一组线程,直到某种预定的条件达到之后,这些之前在等待的线程才会统一出发,继续向下执行。正因为它们有这个相似点,你可能会认为它们的作用是完全一样的,其实并不是。CyclicBarrier 可以构造出一个集结点,当某一个线程执行 await() 的时候,它就会到这个集结点开始等待,等待这个栅栏被撤销。直到预定数量的线程都到了这个集结点之后,这个栅栏就会被撤销,之前等待的线程就

2021-01-29 21:08:26 119

原创 53-CountDownLatch 是如何安排线程执行顺序的?

我们先来介绍一下 CountDownLatch,它是 JDK 提供的并发流程控制的工具类,它是在 java.util.concurrent 包下,在 JDK1.5 以后加入的。下面举个例子来说明它主要在什么场景下使用。比如我们去游乐园坐激流勇进,有的时候游乐园里人不是那么多,这时,管理员会让你稍等一下,等人坐满了再开船,这样的话可以在一定程度上节约游乐园的成本。座位有多少,就需要等多少人,这就是 CountDownLatch 的核心思想,等到一个设定的数值达到之后,才能出发。流程图我们把激流勇进的例子

2021-01-28 23:54:54 223 5

原创 52-信号量能被 FixedThreadPool 替代吗?

了解控制并发流程的工具类,作用就是更容易地让线程之间相互配合,比如让线程 A 等待线程 B 执行完毕后再继续执行,来满足业务逻辑。本次我们从 Semaphore(信号量)开始介绍。Semaphore 信号量介绍从图中可以看出,信号量的一个最主要的作用就是,来控制那些需要限制并发访问量的资源。具体来讲,信号量会维护“许可证”的计数,而线程去访问共享资源前,必须先拿到许可证。线程可以从信号量中去“获取”一个许可证,一旦线程获取之后,信号量持有的许可证就转移过去了,所以信号量手中剩余的许可证要减一。同理

2021-01-27 23:51:09 205 8

原创 51-如何利用 CompletableFuture 实现“旅游平台”问题?

旅游平台问题什么是旅游平台问题呢?如果想要搭建一个旅游平台,经常会有这样的需求,那就是用户想同时获取多家航空公司的航班信息。比如,从北京到上海的机票钱是多少?有很多家航空公司都有这样的航班信息,所以应该把所有航空公司的航班、票价等信息都获取到,然后再聚合。由于每个航空公司都有自己的服务器,所以分别去请求它们的服务器就可以了,比如请求国航、海航、东航等,如下图所示:串行一种比较原始的方式是用串行的方式来解决这个问题。比如我们想获取价格,要先去访问国航,在这里叫作 website 1,然后再去访问海

2021-01-26 22:58:29 167 3

原创 50-使用 Future 有哪些注意点?Future 产生新的线程了吗?

Future 的注意点当 for 循环批量获取 Future 的结果时容易 block,get 方法调用时应使用 timeout 限制对于 Future 而言,第一个注意点就是,当 for 循环批量获取 Future 的结果时容易 block,在调用 get 方法时,应该使用 timeout 来限制。下面我们具体看看这是一个什么情况。首先,假设一共有四个任务需要执行,我们都把它放到线程池中,然后它获取的时候是按照从 1 到 4 的顺序,也就是执行 get() 方法来获取的,代码如下所示:pub

2021-01-25 23:25:52 284

原创 49-Future 的主要功能是什么?

Future 类Future 的作用Future 最主要的作用是,比如当做一定运算的时候,运算过程可能比较耗时,有时会去查数据库,或是繁重的计算,比如压缩、加密等,在这种情况下,如果我们一直在原地等待方法返回,显然是不明智的,整体程序的运行效率会大大降低。我们可以把运算的过程放到子线程去执行,再通过 Future 去控制子线程执行的计算过程,最后获取到计算结果。这样一来就可以把整个程序的运行效率提高,是一种异步的思想。Callable 和 Future 的关系接下来我们介绍下 Callable 和

2021-01-23 23:48:55 150

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除