ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

redis分布式锁

2022-07-18 17:33:38  阅读:168  来源: 互联网

标签:return String redis param Boolean identify lockKey 分布式


由 黄森明创建, 最后修改于2022-七月-11,
1.配置类
@Primary
@Bean("clusterObjectRedisTemplate")
public RedisTemplate<String, Object> objectTemplate(RedisConnectionFactory factory) {

RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// key采用String的序列化方式
template.setKeySerializer(new StringRedisSerializer());
// value序列化方式采用jackson
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;

}
2.获取锁
2.1 lua脚本
private static final String TRY_LOCK_SCRIPT =
"if redis.call('SET',KEYS[1], ARGV[1], 'NX', 'EX', ARGV[2]) " +
"then " +
" return 1 " +
"else" +
" return 0 " +
"end";
2.2 获取锁
/**

  • 获取锁,获取锁成功返回true,获取失败返回false

  • @param lockKey 锁key值

  • @param identify 锁value值,通过value对比释放锁

  • @param expireMillisecond 过期时间

  • @return
    /
    public Boolean lock(String lockKey, String identify, Long expireMillisecond) {
    try {
    RedisScript redisScript = new DefaultRedisScript<>(TRY_LOCK_SCRIPT, Long.class);
    Object result = objectTemplate.execute(redisScript, Collections.singletonList(lockKey), identify, expireMillisecond);
    if (LOCK_SUCCESS.equals(result)) {
    return Boolean.TRUE;
    }
    } catch (Exception e) {
    logger.error("获取锁失败,lockKey=[{}], identify=[{}]", lockKey, identify, e);
    }
    return Boolean.FALSE;
    }
    2.3 尝试多次获取锁
    /
    *

  • 尝试获取锁

  • @param key

  • @param value

  • @param expireMillisecond 过期时间

  • @param waitMillisecond 等待锁的时间
    */
    public Boolean tryLock(String key,String value, Long expireMillisecond, Long waitMillisecond) {
    while(waitMillisecond > 0 ){
    Boolean lockFlag = lock(key, value, expireMillisecond);
    if(lockFlag) {
    return true;
    }else{
    try {
    Thread.sleep(INTERVAL_MILLISECOND);
    } catch (InterruptedException e) {
    logger.error("睡眠中断",e);
    }
    waitMillisecond = waitMillisecond - INTERVAL_MILLISECOND;
    }

    }
    return false;
    }
    3.释放锁
    3.1 lua脚本
    private static final String RELEASE_LOCK_SCRIPT =
    "if redis.call('get', KEYS[1]) == ARGV[1] " +
    "then " +
    " return redis.call('del', KEYS[1]) " +
    "else " +
    " return 0 " +
    "end";
    3.2 释放锁
    /**

  • 释放锁,释放成功返回true,释放失败返回false

  • @param lockKey 锁key值

  • @param identify 判断锁value是否相同,相同才释放锁

  • @return
    /
    public Boolean unLock(String lockKey, String identify) {
    try {
    RedisScript redisScript = new DefaultRedisScript<>(RELEASE_LOCK_SCRIPT, Long.class);
    Object result = objectTemplate.execute(redisScript, Collections.singletonList(lockKey), identify);
    if (LOCK_SUCCESS.equals(result)) {
    return Boolean.TRUE;
    }
    } catch (Exception e) {
    logger.error("解锁失败,lockKey=[{}], identify=[{}]", lockKey, identify, e);
    }
    return Boolean.FALSE;
    }
    4.获取锁测试
    @Test
    public void testLock() throws InterruptedException {
    int threadCount = 4;
    CountDownLatch countDownLatch = new CountDownLatch(threadCount);
    ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
    int j = 1;
    for (int i = 0; i < threadCount; i++) {
    executorService.submit(() -> {
    String uuid = UUIDUtil.getUUID();
    Boolean lock = redisUtil.tryLock("a12312312312dadq", uuid, 8 * 1000L,6
    1000L);
    if (lock) {
    try {
    log.error("线程[{}]正在执行中,uuid:{}", Thread.currentThread().getName(), uuid);
    try {
    Thread.sleep(7000);
    log.error("线程[{}]执行完毕", Thread.currentThread().getName());
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    } finally {
    boolean releaseResult = redisUtil.unLock("a12312312312dadq", uuid);
    log.error("线程[{}]释放redis,uuid:{},释放状态:{}", Thread.currentThread().getName(), uuid, releaseResult);
    }
    } else {
    log.error("线程[{}]获取锁失败", Thread.currentThread().getName());
    }
    countDownLatch.countDown();
    }, j++);
    }
    countDownLatch.await();
    }

标签:return,String,redis,param,Boolean,identify,lockKey,分布式
来源: https://www.cnblogs.com/steven158/p/16491271.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有