利用watch实现Redis乐观锁

乐观锁基于 CAS Compare And Swap )思想(比较并替换),是不具有互斥性,不会产生锁等待而消 耗资源,但是需要反复的重试,但也是因为重试的机制,能比较快的响应。因此我们可以利用redis 来实 现乐观锁。具体思路如下:
1 、利用 redis watch 功能,监控这个 redisKey 的状态值
2 、获取 redisKey 的值
3 、创建 redis 事务
4 、给这个 key 的值 +1
5 、然后去执行这个事务,如果 key 的值被修改过则回滚, key 不加 1
下面用一个秒杀的案例去演示:

public class Second {

    /**
     * 使用乐观锁实现秒杀
     *
     * @param args
     */
    public static void main(String[] args) {
        String redisKey = "lock";
        ExecutorService executorService = Executors.newFixedThreadPool(20);
        try {
            Jedis jedis = new Jedis("xxxxxxxx", 6379);
            jedis.auth("xxxx");
            //初始值
            jedis.set(redisKey, "0");
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 1000; i++) {
            executorService.execute(() ->{
                Jedis jedis1 = new Jedis("xxxxxx", 6379);
                jedis1.auth("xxxx");
                try {
                    jedis1.watch(redisKey);
                    String redisValue = jedis1.get(redisKey);
                    Integer valInteger = Integer.valueOf(redisValue);
                    String userInfo = UUID.randomUUID().toString();
                    //没有秒完
                    if (valInteger < 10) {
                        Transaction tx = jedis1.multi();
                        tx.incr(redisKey);
                        List<Object> list = tx.exec();
                        //秒成功 失败返回空list而不是空
                        if (list != null && list.size() > 0) {
                            System.out.println("用户:" + userInfo + ",秒杀成功!当前成功人数:" + (valInteger + 1));
                        }
                        //版本变化,被别人抢了。
                        else {
                            System.out.println("用户:" + userInfo + ",秒杀失败");
                        }
                    }
                    //秒完了
                    else {
                        System.out.println("已经有10人秒杀成功,秒杀结束");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    jedis1.close();
                }
            });
        }
        executorService.shutdown();
    }
}




//打印日志如下

用户:05d4771f-82ef-4435-98ca-d9e21e60ae46,秒杀失败
用户:987c172a-13d6-469c-ab28-3205ce6fde70,秒杀失败
用户:3dbe8630-171e-4635-a94a-27741c5b2ba2,秒杀成功!当前成功人数:10
已经有10人秒杀成功,秒杀结束
用户:893396ff-40a1-4d75-b957-f5f07310a459,秒杀失败
已经有10人秒杀成功,秒杀结束
用户:cc62637c-af35-4281-8597-f13b2661936f,秒杀失败
已经有10人秒杀成功,秒杀结束
用户:0950e862-883b-420c-b8db-4a70b8dc4886,秒杀失败
用户:7d95ccda-1753-40a0-aa92-60f1cdeb42e2,秒杀失败
已经有10人秒杀成功,秒杀结束
已经有10人秒杀成功,秒杀结束
已经有10人秒杀成功,秒杀结束
用户:d88a9db2-cbf1-4a45-a2b7-edb082279ebf,秒杀失败
用户:202b2a78-4857-4e56-a9a0-5fdcce443fa9,秒杀失败
已经有10人秒杀成功,秒杀结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值