SpringBoot中使用Redis实现分布式锁

4 篇文章 0 订阅
2 篇文章 0 订阅

SpringBoot使用Redis实现分布式锁

分布式锁说明

Java中的锁:当多个线程去访问共享数据时,防止一些操作被覆盖(并发问题),这个时候就需要用到抢锁机制,抢到锁的线程才能进行操作,其余线程等待锁释放并抢到锁才能进行操作,例如Sychonized,Lock等。
分布式锁和java中的锁最大的区别在于共享资源是由多个进程去访问,这时候线程之间的锁机制就无法起到作用了,所以就需要引入一些可以被所有服务都能访问的外部服务来让实现锁,例如数据库,Redis,Zookeeper等

SpringBoot中实现

maven依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

redis配置

spring.redis.hostName = 地址
spring.redis.port = 6379
spring.redis.password = pwd
spring.redis.enableTransactionSupport = false

java代码

package com.servingcloud.foreign.service.common.util;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;


/**
 * @author pengdy
 * @description: redis获取分布式锁
 */
@Component
public class RedisUtilExt {

    /**
     * 默认锁超时时间
     */
    private final static long DEFAULT_TIMEOUT = 30000;
    /**
     * MD5加密密码
     */
    private final static String PWD_KEY = "redis_lock";

    @Resource(
        name = "stringRedisTemplate"
    )
    private RedisTemplate<String, String> stringRedisTemplate;

    public String getSortStr(Object obj){
        String objStr = JSON.toJSONString(obj);
        return MD5Util.generate(PWD_KEY,"1",objStr);
    }

    /**
     * 获取redis锁
     * @param key
     * @return
     */
    public boolean getLock(String key){
        //value值为系统当前时间
        if(stringRedisTemplate.opsForValue().setIfAbsent(key,String.valueOf(System.currentTimeMillis()))){
            //设置超时时间 防止死锁
            stringRedisTemplate.expire(key,DEFAULT_TIMEOUT,TimeUnit.MILLISECONDS);
            return true;
        }
        //获取上锁时间 判断锁是否超时,超时则删除key(redis重启会造成重启时间内一些过期的key未被清理),防止死锁
        String valueTime = stringRedisTemplate.opsForValue().get(key);
        if(StringUtils.isNotEmpty(valueTime) && System.currentTimeMillis()-Long.parseLong(valueTime)>DEFAULT_TIMEOUT){
            //释放锁 再次抢锁
            unLock(key);
            return getLock(key);
        }
        return false;
    }

    /**
     * 释放锁
     * @param key
     */
    public void unLock(String key){
        stringRedisTemplate.opsForValue().getOperations().delete(key);
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值