Redis基础

为啥要用redis锁:

1.分布式锁是控制分布式系统之间同步访问共享资源的一种方式

    传统的加锁方式,只能实现在同一个JVM上的不同线程之间的同步安全,试问如果你的JVM上运行的一个线程的方法和我的线程的运行的方法,通过这种传统的加锁方式,可能同步吗?结果显而易见。此时不禁想到通过一个第三方来实现数据的同步,方法的同步。第一反应就是数据库,进而延伸到redis,在我理解redis就相当于一个数据库。

2.秒杀类似的场景,需要超低粒度的锁

1、秒杀在技术层面的抽象应该就是一个方法,在这个方法里可能的操作是将商品库存-1,将商品加入用户的购物车等等,在不考虑缓存的情况下应该是要操作数据库的。那么最简单直接的实现就是在这个方法上加上synchronized关键字,通俗的讲就是锁住整个方法; 
2、锁住整个方法这个策略简单方便,但是似乎有点粗暴。可以稍微优化一下,只锁住秒杀的代码块,比如写数据库的部分; 
3、既然有并发问题,那我就让他“不并发”,将所有的线程用一个队列管理起来,使之变成串行操作,自然不会有并发问题。

上面所述的方法都是有效的,但是都不好。为什么?第一和第二种方法本质上是“加锁”,但是锁粒度依然比较高。什么意思?试想一下,如果两个线程同时执行秒杀方法,这两个线程操作的是不同的商品,从业务上讲应该是可以同时进行的,但是如果采用第一二种方法,这两个线程也会去争抢同一个锁,这其实是不必要的。第三种方法也没有解决上面说的问题。

 

eg:

private boolean tryLock(int OrderId) {
StoreKey key = new StoreKey("iamakey", OrderId);
return redisClient.add(key, "0");//由key保证唯一性
}
//此时就把OrderId锁住了(前提调用处都执行trylock操作),当然多线程访问的时候这段代码要在循环中以保证当前线程能够执行逻辑代码
//此时无论是同一台机器的其他线程(请求) 还是其它分布式机器的请求都无法对该OrderId进行操作(操作之前调用trylock)。
private boolean releaseLock(int OrderId) {
StoreKey key = new StoreKey("iamakey", OrderId);
return redisClient.delete(key);
}
//此时就把OrderId释放了
posted @ 2017-08-17 23:18  丨核桃牛奶  阅读(208)  评论(0编辑  收藏  举报