Redisson 分布式锁源码 11:Semaphore 和 CountDownLatch

2021-07-15
阅读 2 分钟
2.1k
前言Redisson 除了提供了分布式锁之外,还额外提供了同步组件,Semaphore 和 CountDownLatch。Semaphore意思就是在分布式场景下,只有 3 个凭证,也就意味着同时只会有三个线程执行业务。设置凭证参数列表:KEYS[1]:指定的 key 这里叫 semaphoreKEYS[2]:redisson_sc:{semaphore}ARGV[1]:凭证数 3这块 lua 脚本相对简...

Redisson 分布式锁源码 10:读写锁

2021-07-13
阅读 3 分钟
3.1k
前言Redisson 还支持可重入读写锁,允许在分布式场景下,同时有多个读锁和一个写锁处于加锁状态。使用读写锁Redisson 读写锁实现了 JUC 下的 ReadWriteLock,使用方式基本相同。源码加锁源码基本和之前的可重入锁加锁无区别,唯一的差异就是在 Lua 脚本这里。所以下面着重分析 Lua 脚本。读锁源码源码地址:org.redisson...

Redisson 分布式锁源码 09:RedLock 红锁的故事

2021-07-12
阅读 4 分钟
4.9k
所以本文会先介绍什么是 RedLock,当大家对 RedLock 有一个基本的了解。然后再看 Redisson 中是如何实现 RedLock 的。

Redisson 分布式锁源码 08:MultiLock 加锁与锁释放

2021-07-10
阅读 2 分钟
2.9k
基于 Redis 的 Redisson 分布式联锁 RedissonMultiLock 对象可以将多个 RLock 对象关联为一个联锁,每个 RLock 对象实例可以来自于不同的 Redisson 实例。

Redisson 分布式锁源码 07:公平锁释放

2021-07-09
阅读 1 分钟
2k
看门狗机制是在 RedissonBaseLock#scheduleExpirationRenewal 方法中,这块公平锁和非公平锁并无区别。

Redisson 分布式锁源码 06:公平锁排队加锁

2021-07-08
阅读 2 分钟
3.6k
Redis Hash 数据结构:存放当前锁,Redis Key 就是锁,Hash 的 field 是加锁线程,Hash 的 value 是 重入次数;

Redisson 分布式锁源码 05:公平锁加锁

2021-07-07
阅读 4 分钟
1.9k
前言默认的加锁逻辑是非公平的。在加锁失败时,线程会进入 while 循环,一直尝试获得锁,这时候是多线程进行竞争。就是说谁抢到就是谁的。Redisson 提供了 公平锁 机制,使用方式如下: {代码...} 下面一起看下公平锁是如何实现的?公平锁相信小伙伴们看过前面的文章,已经轻车熟路了,直接定位到源码方法:RedissonFair...

Redisson 分布式锁源码 04:可重入锁释放

2021-07-06
阅读 1 分钟
1.8k
前言前面已经了解到了,可重入锁加锁,看门狗以及锁的互斥阻塞。当锁加锁成功之后,锁是如何释放的?主动释放源码入口:RedissonLock#unlock在解锁时会获取当前线程的id。一路往里跟,直接来到 RedissonLock#unlockInnerAsync:分析一下 lua 脚本的内容:如果锁不存在,直接返回 null;如果锁存在,则对锁的重入次数 -1...

Redisson 分布式锁源码 03:可重入锁互斥

2021-07-05
阅读 1 分钟
2.1k
前言看过可重入锁的 Lua 脚本,已经可以知道当锁存在时,是会加锁失败的。下面看一下,加锁失败之后是如何处理的呢?加锁 Lua 脚本在 lua 脚本中,前两段 if 分别排除了两种情况:锁不存在;锁存在且是自己线程(可重入);剩下的情况就是锁存在,但是不是自己,也就意味着加锁失败。执行 pttl 命令,返回锁的剩余时间。...

Redisson 分布式锁源码 02:看门狗

2021-07-03
阅读 2 分钟
5.5k
前言说起 Redisson,比较耳熟能详的就是这个看门狗(Watchdog)机制。本文就一起看看加锁成功之后的看门狗(Watchdog)是如何实现的?加锁成功在前一篇文章中介绍了可重入锁加锁的逻辑,其中 RedissonLock#tryAcquireAsync 方法是进行异步加锁的逻辑。回顾一下这个方法的入参:waitTime:-1;leaseTime:-1,加锁时未指...

Redisson 分布式锁源码 01:可重入锁加锁

2021-07-02
阅读 4 分钟
4.5k
前言相信小伙伴都是使用分布式服务,那一定绕不开分布式服务中数据并发更新问题!单系统很容易想到 Java 的各种锁,像 synchronize、ReentrantLock 等等等,那分布式系统如何处理?当然是使用分布式锁。如果小伙伴不知道什么是分布式锁,那推荐看看石杉老师的突击课或者在网上搜一搜相关资料。当使用 Redis 作为分布式锁...

Spring @Transactional 注解是如何执行事务的?

2021-06-25
阅读 5 分钟
5.3k
前言相信小伙伴一定用过 @Transactional 注解,那 @Transactional 背后的秘密又知道多少呢?Spring 是如何开启事务的?又是如何进行提交事务和关闭事务的呢?画图猜测在开始 debug 阅读源码之前,小伙伴们应该已经知道 MySQL 是如何开启事务的。因此可以得出猜测:那下面跟着源码一起读一读,Spring 的 @Transactional ...

为了不写接口文档,我肝了个 IDEA 插件!

2021-06-17
阅读 2 分钟
2k
前言写代码的快乐,在于通过一顿猛如虎的操作,实现了自己设计的逻辑流程。(也可能并不是很快乐!)这时候,你以为就可以关机么?还有接口文档没写呢!哈?开始进入无限 CV 模式,各种请求参数、必填非必填、请求返回示例!几分钟后…… 🤬🤬🤬我要写个 IDEA 插件,以后再也不想手写文档了!下面,来看看我肝出来的插件吧!...

工作中的设计模式 —— 建造者模式

2021-04-18
阅读 3 分钟
1.2k
前言建造者模式是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。一个 Builder 类会一步一步构造最终对象。这个 Builder 类是独立于其他对象的。使用场景在阅读源码过程中经常看到建造者模式,主要是为了简化复杂对象的创建。具体那些房子啥的举例子就不扯...

工作中的设计模式 —— 策略模式

2021-04-08
阅读 3 分钟
1.5k
按照上面的 if else 逻辑,其中 aaa、bbb、ccc 就是不同的策略。而使用策略模式的目的,就是当又增加了 ddd、eee 等等的时候,更方便的扩展。

工作中的设计模式 —— 原型模式

2021-04-06
阅读 3 分钟
1k
比如咱们项目中有 BO、DTO、VO,但是在开发过程中,需要各种转换,get/set,一般情况下大家都会使用 BeanUtils,将一个类的属性值 set 到另一个类的属性值中,然后返回。

IDEA 敏捷开发技巧——后缀完成

2021-02-20
阅读 2 分钟
1.6k
前言“工欲善其事,必先利其器。”所以说今天来看一看如何压榨 IDEA ,让你的 IDEA 使用的更顺手!今日技巧:后缀完成自定义后缀完成模版示例上面动图使用了 .sout .if 来举例,相信有些小伙伴在工作中经常使用。如果没有使用过,也可以🦑尝试一下。自定义后缀模版因为打印日志的时候,为了方便日志的查看,一般会将实体打...

Spring 事务、异步和循环依赖有什么关系?

2021-02-02
阅读 4 分钟
2.4k
前言在循环依赖中有一种循环依赖,就是自注入:自己依赖自己。事务的自注入在 Spring 自调用事务失效,你是怎么解决的? 有小伙伴提出可以自己注入自己来解决事务失效。具体使用方式如下: {代码...} 是不是发现很神奇的事情,事务生效了。其实这里注入自己,其实是注入的一个代理对象,调事务,也是调的代理对象的事务...

Spring 是如何解决循环依赖的?

2021-01-26
阅读 5 分钟
16.5k
Requested bean is currently in creation: Is there an unresolvable circular reference?

Spring 源码学习 12:registerBeanPostProcessors

2021-01-02
阅读 7 分钟
2.4k
前面通过 invokeBeanFactoryPostProcessors 这一步了解到了什么是 BeanFactoryPostProcessor ,以及 BeanFactoryPostProcessor 的使用及作用,并通过 invokeBeanFactoryPostProcessors 这一步源码,对 BeanFactoryPostProcessor 的加载流程有了进一步了解。

Spring 源码学习 11:invokeBeanFactoryPostProcessors

2020-12-28
阅读 14 分钟
1.6k
知道了上面两个问题的答案,对 BeanFactoryPostProcessor 有了了解之后,然后再深入源码,继续阅读 invokeBeanFactoryPostProcessors 这个方法。

Spring 源码学习 06:AnnotatedBeanDefinitionReader

2020-12-10
阅读 2 分钟
1.6k
前言BeanDefinition 的概念也了解了,也知道一个 Bean 在 Spring 中定义的信息有哪些之后,继续言归正传。源码分析在初始化时会先生成一个 reader ,进入方法,其实是走的下面的逻辑:其中 getOrCreateEnvironment(registry) 会返回一个 Environment 用来表示当前的运行环境之类的。ConditionEvaluator 是用来完成对 @Co...

Spring 源码学习 05:BeanDefinition 概念及其实现

2020-12-08
阅读 3 分钟
1.4k
BeanDefinition:顾名思义,就是 Bean 的定义,是用来描述一个 Bean 都有什么信息。前面说在初始化 DefaultListableBeanFactory 时,会初始化一个 Map<String, BeanDefinition>,这个 Map 的功能暂且不说,(PS:查资料说的是存储 bean),所以今天就结合官方文档以及源码,一起了解一下 BeanDefinition!

线程池 ThreadPoolExecutor 原理及源码笔记

2020-11-16
阅读 8 分钟
1.1k
前言前面在学习 JUC 源码时,很多代码举例中都使用了线程池 ThreadPoolExecutor,并且在工作中也经常用到线程池,所以现在就一步一步看看,线程池的源码,了解其背后的核心原理。

Spring 自调用事务失效,你是怎么解决的?

2020-11-09
阅读 4 分钟
7.2k
前言相信大家都遇到一种事务失效场景,那就是 Spring 自调用,就是在 Service 方法内,调用另一个加 @Transactional 注解的方法,发现事务失效,这时候你是怎么解决的呢?

写时复制集合 —— CopyOnWriteArrayList

2020-11-08
阅读 5 分钟
2k
前言JUC 下面还有一个系列的类,都是 CopyOnWriteXXX ,意思是写时复制,这个究竟是怎么回事?那就以 CopyOnWriteArrayList 为切入点,一起了解写时复制是怎么回事?

非阻塞的无界线程安全队列 —— ConcurrentLinkedQueue

2020-11-08
阅读 5 分钟
3.8k
前言JUC 下面的相关源码继续往下阅读,这就看到了非阻塞的无界线程安全队列 —— ConcurrentLinkedQueue,来一起看看吧。

APP 莫名崩溃,开始以为是 Header 中 name 大小写的锅,最后发现原来是容器的错!

2020-11-08
阅读 10 分钟
5.3k
前言部署测试,部署预发布,一切测试就绪,上生产。发布生产闪退What???马上回滚开始排查后端一模一样的代码,不是 APP 端的问题吧。可 APP 端没有发版啊。…… 一番排查原来是 APP 端打包,测试和预发布包 Header 传的都是 Authorization ,生产传的是 authorization 。就是大小写问题,那赶紧改。

几行代码轻松实现跨系统传递 traceId,再也不用担心对不上日志了!

2020-11-08
阅读 5 分钟
2.4k
前言新项目查日志太麻烦,多台机器之间查来查去,还不知道是不是同一个请求的。打印日志时使用 MDC 在日志上添加一个 traceId,那这个 traceId 如何跨系统传递呢?

老大问我:“建表为啥还设置个自增 id ?用流水号当主键不正好么?”

2020-11-08
阅读 3 分钟
1.4k
又要开始新项目了,一顿操作猛如虎,梳理流程加画图。这不,开始对流程及表结构了。我:吧啦吧啦吧啦 ……老大:这个建表为啥还设置个自增 id ?直接用流水号(用户号/产品号)当主键不就行了?我:这个是 DBA 规定的,创建表 id、create_time、update_time 这三个字段都要有。《Java 开发规范》也是这么规定的。小伙伴:...