一、前言
redis是一个单线程的服务,那么所有的命令肯定会排队被redis执行,redis提供的命令都是原子性的,百度搜索incrdecr就是说将对应的key+1,key-1的值重新set到redis中,而且很多都是认为incrdecr原子性的,那么现在就有一个问题,如果redis的key:a, value:100,那么100个线程并发执行decr操作,那么对应的key的value是不是应该为0?
按照百度的说法,应该是。-1、-1、-1、-1进行排队等待redis执行,那么总有100的-1,那么value也是100,那么值肯定也是减去100了,最后的值是0?
这样的话,是不是incrdecr可以做秒杀业务,不需要采用锁机制呢?
我们动手试试了下
package redisStockNumber;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @author : fangcong
* @date : 2023/3/22 15:22
* @description : 类作用
**/
public class RedisUtils {
private static JedisPool jedisPool;
static {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20000);
jedisPool = new JedisPool(jedisPoolConfig,"127.0.0.1", 6379);
jedisPool.getResource().set("testNumber", ""+2024);
}
public static void main(String[] args) {
int number = 2024;
for(int i = 0; i < number ; i++){
Thread thread
= new Thread(() -> {
Jedis currentJedis = jedisPool.getResource();
currentJedis.decrBy("testNumber", 1);
});
thread.start();
}
// sleep堵塞等到所有的子线程执行完成。
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Jedis jedis = jedisPool.getResource();
String testNumber = jedis.get("testNumber");
System.out.println(testNumber);
}
}
对应pom
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0</version>
</dependency>
引入一个jedis客户端来操作redis ,我们需要注意这里的jedis是一个非线程安全的类,因此可以使用jedispool对象来获得不同的线程客户端来模拟多个客户端。
我们得到的结果是0,这就说明了incrdecr是我们上述说的那种原理,在多个客户端并发下是线程安全的。
二、为什么不能使用incrdecr来做下单操作呢?
那么如果并发数刚刚有1000个人来购买,那么并发执行1000次,这样库存量减去1000,就剩余0了。
但是如果有1200个人并发,那么就会并发执行1200次,那么库存量就为 -200了,那肯定就是超卖了,因此需要在decr之前进行判断库存量,如果库存量大于0,则进行下单。
Integer num = redis.getKey(a);
if(num > 0){
redis.decr(a,1);
}
但是这里有一个问题,还是之前说的,如果有1200个人并发,那么同时拿到的num不是最新的,因此需要加锁保证这里的num必须是最新的。
RLock lock = redisson.tryLock(a);
lock.lock();
try{
if(num > 0){
redis.decr(a,1);
}
} finally {
//解锁
System.out.println("解锁..."+Thread.currentThread().getId());
lock.unlock();
}
或者使用lua脚本,将业务逻辑封装成lua脚本来保证其执行原子性。
原文地址:https://blog.csdn.net/qq_38240227/article/details/129712818
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_36802.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!