Redisson——RCountDownLatch倒计数器(闭锁)
早睡蛋
# 倒计数器场景
一个线程等待一组线程的执行
例如手机安装软件前的每一步,授权,确认等;或者班长等剩下6名同学出来才能锁门……
# JUC的CountDownLatch
执行原理,我们通过await方法把需要执行的逻辑给阻塞住,然后CountDownLatch的量要减为0后才能执行。
//把这个main线程想象成关门的人
public static void main(String[] args) throws InterruptedException {
//模拟锁门,需要等6位同学出来才能锁门
CountDownLatch countDownLatch = new CountDownLatch(6);
//模拟6名同学
for (int i = 0; i < 6; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + "准备出门。。");
//墨迹一会
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "出门了");
//每出来一名同学,释放一次资源
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, i + "号同学").start();
}
//在这6名同学出来之前,需要对关门的人进行阻塞
countDownLatch.await();
//等6名同学都出来了,可以锁门了
System.out.println(Thread.currentThread().getName() + "可以锁门了");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
0号同学准备出门。。
5号同学准备出门。。
4号同学准备出门。。
3号同学准备出门。。
2号同学准备出门。。
1号同学准备出门。。
4号同学出门了
1号同学出门了
0号同学出门了
3号同学出门了
2号同学出门了
5号同学出门了
main可以锁门了
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Redisson的RCountDownLatch
基于Redisson的Redisson分布式闭锁(CountDownLatch (opens new window))Java对象RCountDownLatch
采用了与java.util.concurrent.CountDownLatch
相似的接口和用法。
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();
// 在其他线程或其他JVM里
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();
1
2
3
4
5
6
7
2
3
4
5
6
7
# 代码实现RCountDownLatch
编写两个接口,分别为主线程方法和需要等待释放的线程方法,执行逻辑:
- 请求latch接口会被阻塞
- 需要执行counDown接口的方法,使得资源量减为0,latch接口才会被放行
@GetMapping("/test/latch")
public String testLatch() {
stockService.testLatch();
return "锁门了!";
}
@GetMapping("/test/countDown")
public String testCountDown() {
stockService.testCountDown();
return "出来了一位同学";
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
编写对应的业务方法:
/**
* 主任务(资源释放为0才能被执行)
*/
public void testLatch() {
RCountDownLatch cdl = redissonClient.getCountDownLatch("cdl");
cdl.trySetCount(6);
try {
cdl.await();
//TODO:一系列操作 准备锁门
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 一组任务(执行完这组任务才能出发主任务的执行)
*/
public void testCountDown() {
RCountDownLatch cdl = redissonClient.getCountDownLatch("cdl");
//TODO:一系列操作 然后资源减一
cdl.countDown();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22