redis保存AtomicInteger对象踩坑及解决

redis保存AtomicInteger对象踩坑

redisTemplate 保存AtomicInteger对象异常:

java.lang.ClassCastException: java.util.concurrent.atomic.AtomicInteger cannot be cast to java.lang.String
    at org.springframework.data.redis.serializer.StringRedisSerializer.serialize(StringRedisSerializer.java:36)
    at org.springframework.data.redis.core.AbstractOperations.rawValue(AbstractOperations.java:127)
    at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:235)
    at com.quan.starter.service.impl.RedisServiceImpl.set(RedisServiceImpl.java:139)

跟踪源码发现其执行的是 StringRedisSerializer 的实现,serialize默认接收的参数类型为String 从而抛出以上异常

经过检查,发现是RedisTemplate泛型惹的祸:

@Autowired
private RedisTemplate<String, String> redisTemplate;

解决方案

去除泛型:

@Autowired
private RedisTemplate redisTemplate;

运行服务再次跟踪源码,执行的是 DefaultValueOperations 的实现,问题解决

RedisAtomicInteger的使用

RedisAtomicInteger 从名字上来说就是 redis 的原子Integer 数据类型,由于其原子性,可用于秒杀活动物品数量的控制。

以及保证顺序生成数字。

@Resource
 RedisTemplate<String, Object> redisTemplate;


 /**
 * RedisAtomicInteger
 *
 * @throws Exception 异常
 */
 @Test
 public void testTransaction1() throws Exception {
 RedisAtomicInteger redisCount = new RedisAtomicInteger("key1", this.redisTemplate.getConnectionFactory());
 redisCount.set(0);
 // 创建 100 个线程 并发执行 increment 操作
 ExecutorService pool = Executors.newFixedThreadPool(10);
 for (int i = 0; i < 100; i++) {
 pool.submit(() -> {
 // 配额码原子变量值增加,每次增加1
 for (int j = 0; j < 100; j++) {
 int count = redisCount.incrementAndGet();
 log.info(Thread.currentThread().getName() + ": " + count);
 }
 });
 }
 }

结果

.
.
.
pool-2-thread-90: 9989
pool-2-thread-61: 9987
pool-2-thread-3: 9986
pool-2-thread-12: 9990
pool-2-thread-25: 9991
pool-2-thread-90: 9992
pool-2-thread-12: 9994
pool-2-thread-61: 9993
pool-2-thread-25: 9995
pool-2-thread-61: 10000
pool-2-thread-12: 9996
pool-2-thread-61: 9997
pool-2-thread-25: 9998
pool-2-thread-12: 9999

作者:夜月如水原文地址:https://blog.csdn.net/w_quan/article/details/105137090

%s 个评论

要回复文章请先登录注册