springboot + redission 实现分布式锁

使用springboot 2.2.2 ,redis 3.0

首先这里的pom文件如下:


   org.redisson
   redisson
   3.5.0



   org.springframework.boot
   spring-boot-starter-web



   org.projectlombok
   lombok
   true

配置文件如下:application.yml

server:
  port: 9030
spring:
  redis:
    database: 1
    host: localhost
    port: 6379
redisson:
  address: redis://127.0.0.1:6379

配置的config类如下:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {

    @Value("${redisson.address}")
    private String addressUrl;

    @Bean
    public RedissonClient getRedisson() throws Exception{
        RedissonClient redisson = null;
        Config config = new Config();
        config.useSingleServer()
                .setAddress(addressUrl);

        //设置看门狗的时间,不配置的话默认30000 
        config.setLockWatchdogTimeout(12000);

        redisson = Redisson.create(config);
        System.out.println(redisson.getConfig().toJSON().toString());
        return redisson;
    }

}

redisson的配置文件如下:

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedissonUtil {
    @Autowired
    private RedissonClient redissonClient; // RedissonClient已经由配置类生成,这里自动装配即可

    /**
     * 锁住不设置超时时间(拿不到lock就不罢休,不然线程就一直block)
     * @param lockKey
     * @return org.redisson.api.RLock
     */
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

    /**
     * leaseTime为加锁时间,单位为秒
     * @param lockKey
     * @param leaseTime
     * @return org.redisson.api.RLock
     */
    public RLock lock(String lockKey, long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(leaseTime, TimeUnit.SECONDS);
        return null;
    }

    /**
     * timeout为加锁时间,时间单位由unit确定
     * @param lockKey
     * @param unit
     * @param timeout
     * @return org.redisson.api.RLock
     */
    public RLock lock(String lockKey, TimeUnit unit, long timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }

    /**
     * 尝试获取锁
     * @param lockKey
     * @param unit
     * @param waitTime
     * @param leaseTime
     * @return boolean
     */
    public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
    }


        /**
     * 尝试获取锁
     * @param lockKey
     * @param unit
     * @param waitTime
     * @param leaseTime
     * @return boolean
     */
    public boolean tryLock(String lockKey,TimeUnit unit, long waitTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime,unit);
        } catch (InterruptedException e) {
            return false;
        }
    }

    /**
     * 通过lockKey解锁
     * @param lockKey
     * @return void
     */
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }

    /**
     * 直接通过锁解锁
     * @param lock
     * @return void
     */
    public void unlock(RLock lock) {
        lock.unlock();
    }

}

controller层的代码如下

import com.exta.redission1.common.RedissonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class testController {

    @Autowired
    private RedissonUtil redissonUtil;

    @RequestMapping("/get1")
    public  String  get1(){
        try{
            log.info("============={} 线程访问开始============",Thread.currentThread().getName());
            //TODO 尝试获取锁,等待5秒,自己获得锁后一直不解锁则7秒后自动解锁
            //boolean lock = redissonUtil.tryLock("lock1", TimeUnit.SECONDS, 5L, 7L);
            //进行5s的尝试时间,如果失败则返回false, 还可以设置锁过期时间,如果设置会导致看门狗无效
            boolean lock = redissonUtil.tryLock("lock1", TimeUnit.SECONDS, 5L);
            if (lock) {
                log.info("线程:{},获取到了锁",Thread.currentThread().getName());
                Thread.sleep(100);
                log.info("======获得锁后进行相应的操作======" + Thread.currentThread().getName());
                //redissonUtil.unlock("lock1");  //释放锁
                log.info("=================" + Thread.currentThread().getName());
            }
        }catch (Exception e){
            log.info("错误信息:{}",e.toString());
            log.info("线程:{} 获取锁失败",Thread.currentThread().getName());
        }
        return "success";
    }
}


开始的时候先把 redissonUtil.unlock("lock1"); 代码给注释掉 通过jemter测试工具可以看到 有很多线程不能执行。把  redissonUtil.unlock("lock1"); 代码打开后则大部分线程都可以得到锁了。

欢迎批评指正。

你可能感兴趣的:(redis,springboot,spring,boot,redis,java)