1、Redis配置

1)

spring.redis:
    host: 127.0.0.1
    port: 6379
    password: 123456

2)

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(host);
        factory.setPort(port);
        factory.setPassword(password);
        factory.setTimeout(8000);
        return factory;
    }

    @Bean
    public RedisConnection jedisClusterConnection() {
        return  jedisConnectionFactory()
                .getConnection();
    }

    @Bean
    public Jedis getJedis() {
        return (Jedis) jedisClusterConnection().getNativeConnection();
    }
}

2、分布式锁类

1)分布式锁

@Component
public class RedisLock {

    @Autowired
    private Jedis jedis;

    private static final String LOCK_SUCCESS = "OK";
    private static final Long RELEASE_SUCCESS = 1L;
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final String EMPTY_STR = "";

    public boolean tryLock(String lockKey, String value, int expireTime) {

        String result = jedis.set(lockKey, value, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
        return LOCK_SUCCESS.equals(result);
    }

    public boolean tryLock(String lockKey, int expireTime) {

        String result = jedis.set(lockKey, EMPTY_STR, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
        return LOCK_SUCCESS.equals(result);
    }

    public boolean releaseLock(String lockKey, String value) {

        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(value));
        return RELEASE_SUCCESS.equals(result);
    }

    public boolean releaseLock(String lockKey) {

        return jedis.del(lockKey) > 0;
    }
}

2、简易版可重入锁

@Component
public class RedisReetrantLock {

    private static final int DEFAULT_EXPIRE_TIME = 5000;

    private ThreadLocal<Map<String, Integer>> locks = new ThreadLocal<>();

    @Autowired
    private RedisLock redisLock;

    private Map<String, Integer> getLocks() {

        Map<String, Integer> lock = locks.get();

        if (Objects.isNull(lock)) {
            lock = Maps.newHashMap();
            locks.set(lock);
        }

        return lock;


    }

    public boolean lock(String key) {

        Map<String, Integer> lock = getLocks();

        Integer num = lock.get(key);

        if (Objects.nonNull(num)) {
            lock.put(key, num + 1);
            return true;
        }

        if (redisLock.tryLock(key, DEFAULT_EXPIRE_TIME)) {
            lock.put(key, 1);
            return true;
        }

        return false;

    }


    public boolean release(String key) {

        Map<String, Integer> lock = getLocks();

        Integer num = lock.getOrDefault(key, 0);

        if (num == 0) {
            return false;
        }

        num --;

        if (num == 0) {
            lock.remove(key);
            redisLock.releaseLock(key);
        } else {
            lock.put(key, num);
        }

        return true;

    }


}