文章目录
- 题记
- 利用Watch实现Redis乐观锁
题记
在线思维导图总结:redis大纲
利用Watch实现Redis乐观锁
乐观锁基于CAS(Compare And Swap)思想(比较并替换),是不具有互斥性,不会产生锁等待而消
耗资源,但是需要反复的重试,但也是因为重试的机制,能比较快的响应。因此我们可以利用redis来实
现乐观锁。具体思路如下:
- 利用redis的watch功能,监控这个redisKey的状态值
- 获取redisKey的值
- 创建redis事务
- 给这个key的值+1
- 然后去执行这个事务,如果key的值被修改过则回滚,key不加1
场景:开启20个线程,模拟100个用户秒杀商品,商品只有三个名额
package com.learn.cache;import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** @author weijie* @date 2020/7/30 13:05*/
public class Demo {public static void main(String[] args) {String rediskey = "lock";ExecutorService executorService = Executors.newFixedThreadPool(20);Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.auth("123456");jedis.set(rediskey, "0");jedis.close();for (int i = 0; i < 100; i++) {executorService.execute(() -> {Jedis jedis2 = new Jedis("127.0.0.1", 6379);jedis2.auth("123456");//监听keyjedis2.watch(rediskey);String redisValue = jedis2.get(rediskey);int v = Integer.parseInt(redisValue);String userInfo = UUID.randomUUID().toString();if (v < 3){//开启redis事务Transaction tx = jedis2.multi();//自增长tx.incr(rediskey);//事务提交List<Object> list = tx.exec();if (list != null && list.size() > 0){System.out.println("用户:" + userInfo + "秒杀成功!当前人数: " + (v + 1));}//版本变化else{System.out.println("用户:" + userInfo + "秒杀失败!");}}else {System.out.println("商品已售空!");}});jedis.close();}executorService.shutdown();}
}