业务场景:
多个客户端并发竞争key,实现操作,保证所有客户端实现串行对key操作成功
设计思路:
采用Redisson客户端实现分布式锁,保证并发操作命令串行化执行,预期结果准确
事例:
设计demo1,demo2,同事有如下代码相当于6个线程并发对anyLock中值进行修改,串行执行,预期结果是330
并发执行demo1 接口:http://127.0.0.1:9999/redissonOpt/makeRedisLockKeyParallel,demo2接口:http://127.0.0.1:9000/redissonOpt/makeRedisLockKeyParallel
package com.szk.app;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* @ProjectName: szk_demo
* @Package: com.szk.app
* @ClassName: RedissonOpt
* @Author: pc
* @Description:
* @Date: 2021/4/29 15:21
*/
@RestController
@RequestMapping("redissonOpt")
public class RedissonOpt {
@Autowired
Redisson redisson;
@Autowired
RedisTemplate redisTemplate;
/**
* @Method
* @Author pc
* @Version 1.0
* @Description 单独测试
* @Param
* @Return
* @Exception
* @Date 2021/5/11
*/
@RequestMapping(value="makeRedisLockKey",method = RequestMethod.POST)
public void makeRedisLockKey(String key){
System.out.println("");
RLock lock = redisson.getLock("anyLock");
lock.lock();
//
boolean flag = lock.isLocked();
if(flag){
redisTemplate.opsForValue().set("anyLock",0);
}
System.out.println(flag);
lock.unlock();
}
/**
* @Method
* @Author pc
* @Version 1.0
* @Description 多线程测试,实现对求和功能
* @Param
* @Return
* @Exception
* @Date 2021/5/11
*/
@RequestMapping(value="makeRedisLockKeyParallel",method = RequestMethod.POST)
public void makeRedisLockKeyParallel(String key){
Thread thread1= new Thread(new Runnable() {
@Override
public void run() {
toValue();
}
});
thread1.setName("004");
thread1.start();
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
toValue();
}
});
thread2.setName("005");
thread2.start();
Thread thread3=new Thread(new Runnable(){
@Override
public void run() {
toValue();
}
});
thread3.setName("006");
thread3.start();
}
/**
* @Method
* @Author pc
* @Version 1.0
* @Description 实现求和
* @Param
* @Return
* @Exception
* @Date 2021/5/11
*/
private void toValue() {
for (int i = 0; i <= 10; i++) {
String ss="当前线程是demo2 " +Thread.currentThread().getName();
System.out.println(ss+" 开始执行。。。。");
RLock lock = redisson.getLock("anyLock");
boolean flag=lock.isLocked();
System.out.println(ss+"检查"+System.currentTimeMillis()+"此时isLocked: "+flag);
lock.lock();
System.out.println(ss+" 获取锁成功");
int count= 0;
try {
count = Integer.valueOf(redisTemplate.opsForValue().get("anyLock").toString());
} catch (NumberFormatException e) {
e.printStackTrace();
}finally {
redisTemplate.opsForValue().set("anyLock",i);
}
count=count+i;
redisTemplate.opsForValue().set("anyLock", count);
System.out.println(ss+"执行结果:"+redisTemplate.opsForValue().get("anyLock"));
lock.unlock();
}
}
}
执行结果:
demo1 执行console:
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 001检查1620701188596此时isLocked: false
当前线程是demo1 002检查1620701188598此时isLocked: false
当前线程是demo1 003检查1620701188599此时isLocked: false
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:0
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 002 获取锁成功
当前线程是demo1 001检查1620701188797此时isLocked: false
当前线程是demo1 002执行结果:0
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 003 获取锁成功
当前线程是demo1 002检查1620701188953此时isLocked: true
当前线程是demo1 003执行结果:0
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701189111此时isLocked: true
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:1
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 001检查1620701189258此时isLocked: false
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:2
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701189409此时isLocked: false
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:3
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701189556此时isLocked: false
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:5
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 001检查1620701189707此时isLocked: false
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:7
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701189862此时isLocked: true
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:9
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701190010此时isLocked: false
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:27
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 001检查1620701191973此时isLocked: true
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:34
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701192288此时isLocked: true
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:173
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701195277此时isLocked: false
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:177
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701195432此时isLocked: false
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:191
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 001 获取锁成功
当前线程是demo1 003检查1620701195743此时isLocked: true
当前线程是demo1 001执行结果:195
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 001检查1620701195904此时isLocked: true
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:200
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:205
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701196221此时isLocked: false
当前线程是demo1 001 获取锁成功
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701196310此时isLocked: true
当前线程是demo1 001执行结果:210
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 001检查1620701196381此时isLocked: true
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:216
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 002 获取锁成功
当前线程是demo1 003检查1620701196539此时isLocked: false
当前线程是demo1 002执行结果:222
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 001 获取锁成功
当前线程是demo1 002检查1620701196694此时isLocked: true
当前线程是demo1 001执行结果:228
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 003 获取锁成功
当前线程是demo1 001检查1620701196843此时isLocked: false
当前线程是demo1 003执行结果:235
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701196990此时isLocked: true
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:242
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 001 获取锁成功
当前线程是demo1 002检查1620701197138此时isLocked: false
当前线程是demo1 001执行结果:249
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:257
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 001检查1620701197568此时isLocked: true
当前线程是demo1 003检查1620701197588此时isLocked: false
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:265
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701197735此时isLocked: false
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:273
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 001检查1620701197884此时isLocked: false
当前线程是demo1 003 获取锁成功
当前线程是demo1 003执行结果:282
当前线程是demo1 003 开始执行。。。。
当前线程是demo1 003检查1620701198034此时isLocked: false
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:291
当前线程是demo1 002 开始执行。。。。
当前线程是demo1 002检查1620701198185此时isLocked: false
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:300
当前线程是demo1 001 开始执行。。。。
当前线程是demo1 003 获取锁成功
当前线程是demo1 001检查1620701198340此时isLocked: true
当前线程是demo1 003执行结果:310
当前线程是demo1 002 获取锁成功
当前线程是demo1 002执行结果:320
当前线程是demo1 001 获取锁成功
当前线程是demo1 001执行结果:330
demo2 执行cosole:
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 005检查1620701189641此时isLocked: true
当前线程是demo2 004检查1620701189643此时isLocked: true
当前线程是demo2 006检查1620701189644此时isLocked: true
当前线程是demo2 004 获取锁成功
当前线程是demo2 004执行结果:9
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701190347此时isLocked: true
当前线程是demo2 006执行结果:9
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 005 获取锁成功
当前线程是demo2 006检查1620701190490此时isLocked: true
当前线程是demo2 005执行结果:9
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 004 获取锁成功
当前线程是demo2 005检查1620701190638此时isLocked: false
当前线程是demo2 004执行结果:10
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701190781此时isLocked: true
当前线程是demo2 006执行结果:11
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 005 获取锁成功
当前线程是demo2 006检查1620701190922此时isLocked: true
当前线程是demo2 005执行结果:12
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 004 获取锁成功
当前线程是demo2 005检查1620701191064此时isLocked: true
当前线程是demo2 004执行结果:14
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701191213此时isLocked: true
当前线程是demo2 006执行结果:16
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 005 获取锁成功
当前线程是demo2 006检查1620701191361此时isLocked: false
当前线程是demo2 005执行结果:18
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 005检查1620701191498此时isLocked: false
当前线程是demo2 004 获取锁成功
当前线程是demo2 004执行结果:21
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701191648此时isLocked: true
当前线程是demo2 006执行结果:24
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 006检查1620701191797此时isLocked: false
当前线程是demo2 004 获取锁成功
当前线程是demo2 004执行结果:31
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 004检查1620701192131此时isLocked: true
当前线程是demo2 006 获取锁成功
当前线程是demo2 006执行结果:38
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 006检查1620701192429此时isLocked: true
当前线程是demo2 005 获取锁成功
当前线程是demo2 005执行结果:41
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 004 获取锁成功
当前线程是demo2 005检查1620701192578此时isLocked: true
当前线程是demo2 004执行结果:46
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701192721此时isLocked: true
当前线程是demo2 006执行结果:51
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 006检查1620701192859此时isLocked: true
当前线程是demo2 005 获取锁成功
当前线程是demo2 005执行结果:55
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 004 获取锁成功
当前线程是demo2 005检查1620701192999此时isLocked: true
当前线程是demo2 004执行结果:61
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701193142此时isLocked: false
当前线程是demo2 006执行结果:67
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 005 获取锁成功
当前线程是demo2 006检查1620701193281此时isLocked: true
当前线程是demo2 005执行结果:72
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 004 获取锁成功
当前线程是demo2 005检查1620701193424此时isLocked: true
当前线程是demo2 004执行结果:79
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701193563此时isLocked: true
当前线程是demo2 006执行结果:86
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 006检查1620701193700此时isLocked: false
当前线程是demo2 005 获取锁成功
当前线程是demo2 005执行结果:92
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 005检查1620701193846此时isLocked: false
当前线程是demo2 004 获取锁成功
当前线程是demo2 004执行结果:100
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701193990此时isLocked: true
当前线程是demo2 006执行结果:108
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 006检查1620701194129此时isLocked: true
当前线程是demo2 005 获取锁成功
当前线程是demo2 005执行结果:115
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 005检查1620701194271此时isLocked: true
当前线程是demo2 004 获取锁成功
当前线程是demo2 004执行结果:124
当前线程是demo2 004 开始执行。。。。
当前线程是demo2 006 获取锁成功
当前线程是demo2 004检查1620701194416此时isLocked: false
当前线程是demo2 006执行结果:133
当前线程是demo2 006 开始执行。。。。
当前线程是demo2 005 获取锁成功
当前线程是demo2 006检查1620701194562此时isLocked: true
当前线程是demo2 005执行结果:141
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 005检查1620701194702此时isLocked: false
当前线程是demo2 004 获取锁成功
当前线程是demo2 004执行结果:151
当前线程是demo2 006 获取锁成功
当前线程是demo2 006执行结果:161
当前线程是demo2 005 获取锁成功
当前线程是demo2 005执行结果:170
当前线程是demo2 005 开始执行。。。。
当前线程是demo2 005检查1620701195132此时isLocked: true
当前线程是demo2 005 获取锁成功
当前线程是demo2 005执行结果:187
预期验证分析:
以上不难发现整个最终结果是330 符合我们预期