一种控制方法并发的注解方法,@Ylock

一、介绍@Ylock

控制多个方法之间的调用关系,帮助解决并发请求修改统一数据造成的数据不一致问题;

二、使用说明

2.1、引入模块

<dependency>
    <groupId>me.yyk</groupId>
    <artifactId>lock4j</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

如图所示


2.2、配置参数

//注解控制需要扫描的包
ylock.path=me.yyk.*
//引入项目中的 StringRedisTemplate 注入的bean名称
ylock.ylockRedisBeanName=redisCache
//最长上锁时间
ylock.lockTimeout=10

如图所示

注意:

该项目依赖于redis,建议springBoot 版本 2.2.0以上


2.3、在方法上加入注解@YLock

2.3.1、“互斥模式”

@GetMapping("/t")
@YLock(configName = "123",name = "hello")
public String hello(@RequestParam("name") String name) throws InterruptedException {
    Thread.sleep(5000);
    return "helloMEthod1";
}
@GetMapping("/t1")
@YLock(configName = "123",name = "hello1")
public String hello1(@RequestParam("name") String name) throws InterruptedException {
    Thread.sleep(5000);
    return "helloMEthod2";
}

分别在hello()和hello1()上加入如上注解,此配置通过configName属性将两个方法纳入到一个锁中管理,得到的效果是:当入参name参数相同时,访问hello() 那么 无法访问hello1()

演示效果:

当我们访问hello()方法,在此方法未执行完成时,访问hello1(),返回如下值

@YLock(configName = "123",name = "hello1",returnInfo = "自定义的返回值")

自定义返回值,定义returnInfo即可

2.3.1、“等待模式”

@GetMapping("/t")
@YLock(configName = "123",name = "hello")
public String hello(@RequestParam("name") String name) throws InterruptedException {
    Thread.sleep(3000);
    return "helloMEthod";
}

@GetMapping("/t1")
@YLock(configName = "123",name = "hello1",mode = MethodLockUnit.Mode.WAIT,holdTime = 3)
public String hello1(@RequestParam("name") String name) throws InterruptedException {
    Thread.sleep(5000);
    return "helloMEthod";
}

如上在hello1()方法中配置,mode = MethodLockUnit.Mode.WAIT , holdTime = 3,当hello()在执行时,hello1()方法可以等待holdTime 单位 秒,在重新判断锁的状态,然后发起执行;

2.3.2、"主锁模式"

@GetMapping("/t")
@YLock(configName = "123",name = "hello")
public String hello(@RequestParam("name") String name) throws InterruptedException {
    Thread.sleep(3000);
    return "helloMEthod";
}

@GetMapping("/t1")
@YLock(configName = "123",name = "hello1",locked = false)
public String hello1(@RequestParam("name") String name) throws InterruptedException {
    Thread.sleep(5000);
    return "helloMEthod";
}

区别于2.3.1的”互斥模式“,当配置helle1()方法 locked = false,那么程序访问hello1(),是不会上锁的,此时其他请求时可以访问hello()方法,反之则不然,访问hello()方法,会更根据参数上锁;

2.4、提示

2.4.1、自定义加锁的KEY

在实际开发过程中,会遇到需要加锁的方法,没有参数,或者参数不同,是根据参数中的某些值来固定的,此时如何做呢;

本模块提供了自定义key的方法;

@GetMapping("/t2")
@YLock(configName = "123",name = "hello2" )
public String hello2(){
    return "helloMEthod";
}

@GetMapping("/t3")
@YLock(configName = "123",name = "hello3")
public String hello3(){
    return "helloMEthod";
}

如上图所示为两个没有参数的方法,此时如使用默认”互斥锁定“的配置,那么会抛出异常无法锁定,如下图所示:

模块会发出错误和报警,此时@Ylock注解是不生效的;

那么请新建类,实现 MethodGetKey 的接口方法

/**
 * @Classname TestGetKey
 * @Description TODO
 * @Date 2022/3/30 14:50
 * @Created by yuyangkang
 */
public class TestGetKey implements MethodGetKey {
    public TestGetKey() {
    }
    @Override
    public String getKey(Object... args) {
        return "987678990";
    }
}

并将原加锁方法增加参数配置 obtainKey =TestGetKey.class

@GetMapping("/t2")
@YLock(configName = "123",name = "hello2",obtainKey =TestGetKey.class )
public String hello2(){
    return "helloMEthod";
}

@GetMapping("/t3")
@YLock(configName = "123",name = "hello3",obtainKey =TestGetKey.class )
public String hello3(){
    return "helloMEthod";
}

此两方法即可实现锁定;

同样当两个锁定的方法入参,不相同时那么请各自定义不同的obtainKey的参数,实现返回的key值相同;

源码地址:

root/Ylock: Ylock4j使用说明: @ ylock4j - yyk

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值