Redis 整合Redis分布式锁

1. 分布式锁

  A. Spring Integration提供多种方式实现分布式锁:Redis、Zookeeper和JDBC等;

  B. Spring Integration分布式锁优点是:可重入且防死锁;

  C. 应用场景:多实例部署,同时只能一个服务获取锁。

2. Maven依赖

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

3. 分布式锁配置

package com.ruhuanxingyun.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;

/**
* @description: 分布式锁配置
* @author: ruphie
* @date: Create in 2020/11/24 21:22
* @company: ruhuanxingyun
*/
@Configuration
public class RedisLockConfig {

@Bean(destroyMethod = "destroy")
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "rhxy");
}

}

4. 示例代码


package com.ruhuanxingyun.redis.controller;

import com.ruhuanxingyun.redis.service.RedisLockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @description: Redis分布式锁 控制层
* @author: ruphie
* @date: Create in 2020/11/24 21:25
* @company: ruhuanxingyun
*/
@RestController
@RequestMapping("/api/redis")
public class RedisLockController {

private static final String LOCK_KEY = "cs";

@Autowired
private RedisLockService redisLockService;

@RequestMapping("/lock")
public void lock() {
for (int i = 0; i < 5; i++) {
new Thread(() -> {
redisLockService.lock(LOCK_KEY);
System.out.println(String.format("线程名%s获取锁", Thread.currentThread().getName()));

try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}

redisLockService.unlock(LOCK_KEY);
System.out.println(String.format("线程名%s释放锁", Thread.currentThread().getName()));
}).start();
}
}

}

package com.ruhuanxingyun.redis.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;

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

/**
* @description: Redis分布式锁 服务层
* @author: ruphie
* @date: Create in 2020/11/24 21:26
* @company: ruhuanxingyun
*/
@Service
public class RedisLockService {

private static final long DEFAULT_EXPIRE_UNUSED = 60000L;

@Autowired
private RedisLockRegistry redisLockRegistry;

/**
* 获取锁,如果锁不可用则线程一直等待
*
* @param lockKey 锁键名
*/
public void lock(String lockKey) {
Lock lock = redisLockRegistry.obtain(lockKey);
lock.lock();
}

/**
* 尝试获取锁,获取失败直接返回false
*
* @param lockKey 锁键名
* @return 是否获取锁
*/
public boolean tryLock(String lockKey) {
Lock lock = redisLockRegistry.obtain(lockKey);

return lock.tryLock();
}

/**
* 可超时获取锁,指定超时时间结束返回false
*
* @param lockKey 锁键名
* @param seconds 超时时间
* @return 是否获取锁
*/
public boolean tryLock(String lockKey, long seconds) {
Lock lock = redisLockRegistry.obtain(lockKey);

try {
return lock.tryLock(seconds, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();

return false;
}
}

/**
* 释放锁
*
* @param lockKey 锁键名
*/
public void unlock(String lockKey) {
Lock lock = redisLockRegistry.obtain(lockKey);
lock.unlock();

redisLockRegistry.expireUnusedOlderThan(DEFAULT_EXPIRE_UNUSED);
}

}

 5. 结果展示

 

可参考:分布式锁的实现与原理解析

posted @ 2020-11-24 15:08  如幻行云  阅读(723)  评论(0编辑  收藏  举报