redis锁 工具类

基于 org.springframework.data.redis.core.RedisOperations做的一个REDIS-SETNX分布式锁。

/*
 * Copyright (c) 2019. 唐江华 保留所有权。
 */



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisOperations;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @author tangjianghua
 * date 2020/4/8
 * time 9:58
 */
public class RedisLock implements Lock {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private String key;

    private final String value = "LOCK";

    private RedisOperations redisOperations;

    /**
     * 尝试获取锁的间隔 1s
     */
    private final long INTERVAL = 1000L;

    /**
     * 获取锁的最大尝试次数
     */
    private final int MAXTRY = 10;

    /**
     * 获取锁状态
     * true:获取到锁
     * false: 为获取到锁
     */
    private boolean lock = false;

    /**
     * 默认超时时间 10分钟
     */
    private final long DEFAILT_EXPIRE = 10L;

    /**
     * 默认超时单位
     */
    private final TimeUnit DEFAILT_UNIT = TimeUnit.MILLISECONDS;

    public RedisLock(RedisOperations redisOperations,String key) {
        this.key = key;
        this.redisOperations =redisOperations;
    }

    @Override
    public void lock() {
        this.lock = redisOperations.opsForValue().setIfAbsent(key, value);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
      //TODO
    }

    @Override
    public boolean tryLock() {
        int i = 0;
        do{
            logger.info("线程"+Thread.currentThread().getId()+"--第"+i+"次尝试获取锁--"+key);
            lock();
            if(!lock){
                try {
                    Thread.sleep(INTERVAL);
                    i++;
                    continue;
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }else {
                logger.info("线程"+Thread.currentThread().getId()+"--获取到锁--"+key);
                break;
            }
        }while (i < MAXTRY);
        return lock;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit){
        if(time == 0L){
            time = DEFAILT_EXPIRE;
        }
        if(unit == null){
            unit = DEFAILT_UNIT;
        }
        if(!tryLock()){
            return false;
        }
        Boolean aBoolean = redisOperations.expire(key, time, unit);
        if(!aBoolean){
            unlock();
        }
        logger.info("线程"+Thread.currentThread().getId()+"--为锁添加超时--"+key+"--"+time+"--"+unit.name());
        return aBoolean;
    }


    /**
     * 默认超时获取锁
     * @return
     */
    public boolean tryLockDefaultExpire(){
        return  tryLock(0L, null);
    }

    @Override
    public void unlock() {
        if(!lock){
            logger.info("线程"+Thread.currentThread().getId()+"--未获取到锁,无需释放--"+key);
          return;
        }
        redisOperations.delete(key);
        this.lock = false;
        logger.info("线程"+Thread.currentThread().getId()+"--释放锁--"+key);
    }

    /**
     * 是否拥有锁
     * @return
     */
    public boolean isLock(){
        return lock;
    }

    @Override
    public Condition newCondition() {
        return null;
    }
}
发布了175 篇原创文章 · 获赞 39 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/top_explore/article/details/105678660