|NO.Z.00051|——————————|BigDataEnd|——|Hadoop&Redis.V04|——|Redis.v04|乐观锁|分布式锁|Redisson.v01|
一、分布式锁/watch/setnx:watch
### --- [Redis经典问题解析]
~~~ [Redis乐观锁]
~~~ [Redis分布式锁]
~~~ [Redisson]
~~~ [Redis分布式锁watch/setnx]
~~~ [Redisson分布式锁的使用/实现原理]
~~~ [分布式锁特性]
~~~ [分布式锁的实际应用]
### --- 利用Watch实现Redis乐观锁
~~~ 乐观锁基于CAS(Compare And Swap)思想(比较并替换),
~~~ 是不具有互斥性,不会产生锁等待而消耗资源,但是需要反复的重试,
~~~ 但也是因为重试的机制,能比较快的响应。
~~~ 因此我们可以利用redis来实现乐观锁。具体思路如下:
~~~ 利用redis的watch功能,监控这个redisKey的状态值
~~~ 获取redisKey的值
~~~ 创建redis事务
~~~ 给这个key的值+1
~~~ 然后去执行这个事务,如果key的值被修改过则回滚,key不加1
二、Redis乐观锁实现秒杀
public class Second {
public static void main(String[] arg) {
String redisKey = "lock";
ExecutorService executorService = Executors.newFixedThreadPool(20);
try {
Jedis jedis = new Jedis("127.0.0.1", 6378);
// 初始值
jedis.set(redisKey, "0");
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < 1000; i++) {
executorService.execute(() -> {
Jedis jedis1 = new Jedis("127.0.0.1", 6378);
try {
jedis1.watch(redisKey);
String redisValue = jedis1.get(redisKey);
int valInteger = Integer.valueOf(redisValue);
String userInfo = UUID.randomUUID().toString();
// 没有秒完
if (valInteger < 20) {
Transaction tx = jedis1.multi();
tx.incr(redisKey);
List 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("已经有20人秒杀成功,秒杀结束");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
jedis1.close();
}
});
}
executorService.shutdown();
}
}
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
浙公网安备 33010602011771号