Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/lockPublic

The distributed lock tool for java.(java 实现开箱即用基于 redis 的分布式锁,支持可重入锁获取。内置整合 spring、springboot。)

License

NotificationsYou must be signed in to change notification settings

houbb/lock

Repository files navigation

lock 为 java 设计的渐进式分布式锁,开箱即用,纵享丝滑。

Maven CentralBuild StatusCoverage Status

开源地址:https://github.com/houbb/lock

目的

  • 开箱即用,支持注解式和过程式调用

  • 支持可重入锁获取

  • 基于 mysql 的分布式锁

  • 基于 redis 的分布式锁

  • 内置支持多种 redis 的整合方式

  • 渐进式设计,可独立于 spring 使用

  • 整合 spring

  • 整合 spring-boot

变更日志

变更日志

快速开始

需要

jdk1.7+

maven 3.x+

基于 MAP 的分布式锁

maven 引入

<dependency>    <groupId>com.github.houbb</groupId>    <artifactId>lock-core</artifactId>    <version>1.7.2</version></dependency>

入门例子

基于本地 MAP 的入门测试案例。

ILocklock =LockBs.newInstance();Stringkey ="ddd";try {// 加锁booleanlockFlag =lock.tryLock(key);Assert.assertTrue(lockFlag);}catch (Exceptione) {thrownewRuntimeException(e);}finally {// 释放锁lock.unlock(key);}

接口说明

接口方法文档

方法签名参数说明返回值说明版本标记
boolean tryLock(final ILockContext context)context: 锁操作上下文对象加锁成功返回 true,失败 falsesince 1.5.0
boolean tryLock(String key, TimeUnit timeUnit, long lockTime, long waitLockTime, boolean reentrant)key: 锁标识
timeUnit: 时间单位
lockTime: 锁持有时长
waitLockTime: 最大等待时长
reentrant: 是否允许重入
加锁成功返回 true,失败 falsesince 1.5.0
boolean tryLock(String key, TimeUnit timeUnit, long lockTime, long waitLockTime)key: 锁标识
timeUnit: 时间单位
lockTime: 锁持有时长
waitLockTime: 最大等待时长
(默认 reentrant=true)
加锁成功返回 true,失败 falsesince 0.0.1
boolean tryLock(String key, TimeUnit timeUnit, long lockTime)key: 锁标识
timeUnit: 时间单位
lockTime: 锁持有时长
(默认 waitLockTime=0 仅尝试一次)
加锁成功返回 true,失败 falsesince 0.0.1
boolean tryLock(String key, long lockTime)key: 锁标识
lockTime: 锁持有时长(秒)
(默认 timeUnit=SECONDS)
加锁成功返回 true,失败 falsesince 0.0.1
boolean tryLock(String key)key: 锁标识
(默认 lockTime=10秒)
加锁成功返回 true,失败 falsesince 0.0.1
boolean unlock(String key)key: 锁标识
注意: 释放锁不重试,所有 key 有过期时间
释放成功返回 true,失败 falsesince 0.0.1

tryLock 方法说明

提供了较多方法,只是为了使用更加便捷。

boolean tryLock(final ILockContext context); 中的入参,和参数一一对应,默认值也相同。

context 的引入,为了避免后续的配置项较多,方法会膨胀的问题。

ILockContextlockContext =LockContext.newInstance()        .key(key)        .lockTime(LockConst.DEFAULT_LOCK_TIME)        .waitLockTime(LockConst.DEFAULT_WAIT_LOCK_TIME)        .reentrant(LockConst.DEFAULT_REENTRANT)        .timeUnit(LockConst.DEFAULT_TIME_UNIT);booleanlockFlag =lock.tryLock(lockContext);

锁的一些特性

锁的可重入性

概念:可重入性(reentrancy)是指一个线程在拥有一个资源(通常是一个锁)的情况下,再次获取该资源时不会造成死锁。可重入性在多线程编程中非常重要,因为它可以避免因线程之间的相互依赖而导致的死锁。

可重入的例子

我们支持一个线程可以多次获取一个锁,默认是可重入的。

@TestpublicvoidreTest() {ILocklock =LockBs.newInstance();Stringkey ="ddd";try {// 加锁booleanlockFlag =lock.tryLock(key);//1. 首次获取锁成功Assert.assertTrue(lockFlag);//2. 重新获取锁成功booleanreLockFlag =lock.tryLock(key);Assert.assertTrue(reLockFlag);    }catch (Exceptione) {thrownewRuntimeException(e);    }finally {// 释放锁lock.unlock(key);    }}

不可重入的例子

当然,我们也支持不可重入的形式,指定对应的配置即可。

publicvoidnoReTest() {ILocklock =LockBs.newInstance();Stringkey ="ddd";try {ILockContextlockContext =LockContext.newInstance()                .key(key)                .waitLockTime(5)                .reentrant(false);// 指定不可重入booleanlockFlag =lock.tryLock(lockContext);//1. 首次获取锁成功Assert.assertTrue(lockFlag);//2. 不是重入,第二次获取失败booleanreLockFlag =lock.tryLock(lockContext);Assert.assertFalse(reLockFlag);    }catch (Exceptione) {thrownewRuntimeException(e);    }finally {// 释放锁lock.unlock(key);    }}

不可重入锁,第二次获取就会失败。

配置化

为了便于拓展,LockBs 的配置支持自定义:

LockBs.newInstance()        .id(Ids.uuid32())//id 生成策略        .cache(JedisRedisServiceFactory.pooled("127.0.0.1",6379))//缓存策略        .lockSupport(newRedisLockSupport())// 锁实现策略        .lockKeyFormat(newLockKeyFormat())// 针对 key 的格式化处理策略        .lockReleaseFailHandler(newLockReleaseFailHandler())//释放锁失败处理        ;

可配置项如下:

属性配置说明

属性名类型默认值说明版本标记
idIdIds.uuid32()唯一标识生成策略since 0.0.4
cacheICommonCacheServicenew CommonCacheServiceMap()缓存实现策略since 0.0.4
lockSupportILockSupportnew CommonCacheLockSupport()锁底层支持策略since 1.0.0
lockKeyFormatILockKeyFormatnew LockKeyFormat()锁 Key 格式化处理器since 1.2.0
lockReleaseFailHandlerILockReleaseFailHandlernew LockReleaseFailHandler()锁释放失败处理策略since 1.2.0
tryLockIntervalMillsintLockConst.DEFAULT_TRY_LOCK_INTERVAL_MILLS尝试加锁的轮询间隔(毫秒)since 1.6.0

整合 spring

maven 引入

<dependency>    <groupId>com.github.houbb</groupId>    <artifactId>lock-spring</artifactId>    <version>1.7.2</version></dependency>

指定 bean 使用

启用分布式锁

@EnableLock 启用分布式锁。

@EnableRedisConfig 启用 redis 的默认配置。

@Configurable@ComponentScan(basePackages = "com.github.houbb.lock.test.service")@EnableLock@EnableRedisConfigpublic class SpringConfig {}

EnableLock 注解说明,和引导类对应:

@EnableLock 注解属性说明

属性名描述默认值
id()唯一标识生成策略"lockId"
cache()缓存实现策略的 Bean 名称"springRedisService"
lockKeyFormat()加锁 Key 格式化策略"lockKeyFormat"
lockKeyNamespace()锁 Key 的默认命名空间LockConst.DEFAULT_LOCK_KEY_NAMESPACE
lockReleaseFailHandler()锁释放失败处理类"lockReleaseFailHandler"

其中springRedisService 使用的是redis-config 中的实现。

对应注解@EnableRedisConfig,redis 的配置信息如下:

配置说明默认值
redis.addressredis 地址127.0.0.1
redis.portredis 端口6379
redis.passwordredis 密码

当然,你可以使用自己想用的其他缓存实现,只需要实现对应的接口标准即可。

使用 LockBs

我们可以直接LockBs 的引导类,这种适合一些更加灵活的场景。

@ContextConfiguration(classes =SpringConfig.class)@RunWith(SpringJUnit4ClassRunner.class)publicclassSpringServiceRawTest {@AutowiredprivateUserServiceuserService;@AutowiredprivateLockBslockBs;@TestpublicvoidqueryLogTest() {finalStringkey ="name";try {booleanlockFlag =lockBs.tryLock(key);finalStringvalue =userService.rawUserName(1L);        }catch (Exceptionexception) {thrownewRuntimeException(exception);        }finally {lockBs.unlock(key);        }    }}

aop 注解使用

指定方法注解

当然,我们可以在方法上直接指定注解@Lock,使用更加方便。

直接使用,AOP 切面生效即可。

@ServicepublicclassUserService {@LockpublicStringqueryUserName(LonguserId) {    }@Lock(value ="#user.name")publicvoidqueryUserName2(Useruser) {    }}

@Lock 属性说明,value 用于指定 key,支持 SPEL 表达式。

如果 aop 中拦截获取锁失败,默认会抛出异常。

其他属性,和引导类的方法参数一一对应。

@Lock 注解属性说明

属性名类型默认值说明
value()String""锁的 Key 策略(支持 SpEL 表达式)
例:@Lock("order:#{#orderId}")
timeUnit()TimeUnitTimeUnit.SECONDS时间单位(秒/毫秒等)
waitLockTime()longLockConst.DEFAULT_WAIT_LOCK_TIME等待锁的最长时间
通常为 0(仅尝试一次)或正数(持续重试)
lockTime()longLockConst.DEFAULT_LOCK_TIME锁持有时间
通常为 10-30 秒(防止死锁)
reentrant()booleanLockConst.DEFAULT_REENTRANT是否允许重入
通常为 true(同一线程可重复获取)

spring boot 整合

maven 引入

<dependency>    <groupId>com.github.houbb</groupId>    <artifactId>lock-springboot-starter</artifactId>    <version>1.7.2</version></dependency>

使用

所有的配置会自动生效。

使用方式同 spring。

后期 Road-MAP

  • 支持锁的可重入

持有锁的线程可以多次获取锁

  • 分布式锁注解支持

  • spring 的锁支持拓展性扩展,而不是局限于 redis-lock

  • watch-dog,添加锁的自动续租?

拓展阅读

Redis 分布式锁

java 从零实现 redis 分布式锁

开源矩阵

下面是一些缓存系列的开源矩阵规划。

名称介绍状态
resubmit防止重复提交核心库已开源
rate-limit限流核心库已开源
cache手写渐进式 redis已开源
lock开箱即用的分布式锁已开源
common-cache通用缓存标准定义已开源
redis-config兼容各种常见的 redis 配置模式已开源
quota-server限额限次核心服务待开始
quota-admin限额限次控台待开始
flow-control-server流控核心服务待开始
flow-control-admin流控控台待开始

About

The distributed lock tool for java.(java 实现开箱即用基于 redis 的分布式锁,支持可重入锁获取。内置整合 spring、springboot。)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp