前端时间做了一个需求 处理数据的 因为数据量比较大 ,当然不可能使用单线程去跑啦 ,不然炸穿了,所以 就考虑使用redis来做分布式锁做分段处理数据
所以今天就临时编写了一个demo记录一下
大概玩法就是 几条线程去从一个数据拿数据 处理,线程之间拿数据时候互不影响且不会出现 重复处理的情况。
1.首先的话 是引入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
2.代码实现 其实很简单的
创建接口类并提供一个接口和实现
这里我就直接晒出代码了
@Override
public void task() {
//创建数组并放入1-10 10个数
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add(i);
}
//这里使用uuid作为处理线程的标识
String value = UUID.randomUUID().toString().replace("-", "");
//获取总页码 这个我随便设置的
String testPage = "5";
//开始进行死循环递归去拿锁处理业务逻辑
while (true){
//创建key,锁的唯一标识
RLock rLock = redisson.getLock(CacheKeys.getLock());
try {
//设置锁的过期时间 设置为-1的话是开启监视狗的机制 为我们的锁续期以及一些别的功能, 防止出现 线程没处理完 锁就到时间释放了,或者A进来执行完了 还没到过期时间 然后B进来 执行 然后删除错了锁 等等情况
rLock.lock(-1, TimeUnit.SECONDS);
String strKey = redisCacheManager.get(CacheKeys.getPage());
// 这里判断redis取当前需要处理了第几页
if (strKey==null){
strKey="1";
redisCacheManager.set(CacheKeys.getDevicePage(),strKey);
}
int page = Integer.parseInt(strKey);
if (page>Integer.parseInt(testPage)){
redisCacheManager.expire(CacheKeys.getDevicePage(),30);
rLock.unlock();
break;
}
//将页数加1 并更新redis
redisCacheManager.set(CacheKeys.getDevicePage(),page+1+"");
//释放锁
rLock.unlock();
//执行业务逻辑
List data = PageUtil.startPage(list, page, 2);
log.info("线程value:{}处理了第:{}页,数据为:{}",value,page,data);
}catch (Exception e){
throw new RuntimeException(e);
}finally {
//最后判断锁是否有释放
RLock lock = redissonClient.getLock(CacheKeys.getLock());
if(lock.isLocked()) {
// 是否还是锁定状态
if (lock.isHeldByCurrentThread()) {
lock.unlock(); // 释放锁
}
}
}
}
}
3.模拟线程执行
@Autowired
TestService testService;
@ApiOperation(value = "模拟多副本执行",notes="模拟多副本执行")
@GetMapping("/threadOnAndOff")
public R threadTest(){
int corePoolSize = 3;//核心线程数
int maximumPoolSize = 50;//最大线程数
long KeepAliveTime = 2;//线程空闲时间
TimeUnit unit = TimeUnit.SECONDS;//时间单位维度
BlockingQueue workQueue = new LinkedBlockingQueue<>(1000);//阻塞队列
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor customThreadPoolExecutor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,KeepAliveTime,unit,workQueue);
//设置5条线程去执行
for( int i=0; i<5; i++) {
customThreadPoolExecutor.execute(new ThreadEnergyTask());
}
return R.OK();
}
class ThreadEnergyTask extends Thread{
public void run() {
testService.task();
}
执行结果展示
以上就是了实现redission分布式锁实现了。