栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

redis实现分布式线程锁

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

redis实现分布式线程锁

配置pom文件

 配置Bean

@Bean
    public DefaultRedisScript defaultRedisScript() {
        DefaultRedisScript defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setResultType(Long.class);
        defaultRedisScript.setScriptText("if redis.call('get', KEYS[1]) == KEYS[2] then return redis.call('del', KEYS[1]) else return 0 end");
        return defaultRedisScript;
    }

写一个获取线程锁和解锁的工具类

@Slf4j
@Component
public class Lock {
    @Autowired
    private StringRedisTemplate redisTemplate;

    public Boolean lockEnable(String key, long expire) {

        //这是将当前线程的名字置为key的value值,表明该锁被谁拿到
        String keyValue = Thread.currentThread().getName();

        //1,这是StringRedisTemplate在set key的同时增加了过期时间,防止死锁。保证了原子性。
        //2,setIfAbsent该方法如果该key不存在时候,设置值进去后,返回true;若是已经存在,则返回false;
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(key, keyValue, expire, TimeUnit.SECONDS);
        Long surplusTime = redisTemplate.getExpire(key, TimeUnit.SECONDS);
        if (!aBoolean) {
            log.info("该线程【{}】加锁失败,该key【{}】剩余过期时间【{}】秒", keyValue, key, surplusTime);
            return false;
        }
        log.info("该线程【{}】加锁成功,该key【{}】剩余过期时间【{}】秒", keyValue, key, surplusTime);
        return true;
    }

    @Autowired
    private DefaultRedisScript redisScript;

    public Boolean lockUnable(String key) {
        String keyValue = Thread.currentThread().getName();
        //key和value不一致时,返回:【0】
        //key和value一致时,返回:【1】
        Long execute = redisTemplate.execute(redisScript, Arrays.asList(key, keyValue));
        if(execute != 1 ){
            Boolean aBoolean = redisTemplate.hasKey(key);
            Long surplusTime = redisTemplate.getExpire(key, TimeUnit.SECONDS);
            log.info("该key【{}】解锁失败,是否存在【{}】,剩余过期时间【{}】秒", key, aBoolean, surplusTime);
            return false;
        }
        log.info("该key【{}】解锁成功", key);
        Boolean aBoolean = redisTemplate.hasKey(key);
        log.info("该key是否存在【{}】",aBoolean);
        return true;
    }
}

在测试单元多线程调用

@Test
    public void catchData() {
        for (int i = 0; i <100; i++) {
            Thread thread = new Thread(() -> {
                threadTest();
            });
            thread.start();
            thread.setName("thread" + i);
        }
        while (true){

        }
    }
    void threadTest(){
        Boolean aBoolean = lock.lockEnable("狄仁杰", 600);


        if (!aBoolean) {
            log.info("线程【{}】没有拿到锁,结束流程",Thread.currentThread().getName());
            return;
        }
        
        log.info("线程【{}】更新数据成功",Thread.currentThread().getName());


        
        Boolean aBoolean1 = lock.lockUnable("狄仁杰");
        log.info("线程【{}】是否成功释放锁:【{}】",Thread.currentThread().getName(),aBoolean1);
    }

运行看效果

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1008733.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号