在Spring boot应用中使用Redisson时出现一个奇怪的异常:
java.lang.ClassCastException: java.lang.Long cannot be cast to [B
后来发现是由于使用了默认注入的RedissionClient对象导致的!看下面的单元测试代码:
...
@Slf4j
public class LockTest extends BaseTest {
private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(20, 2000, 30, TimeUnit.MINUTES, new ArrayBlockingQueue<>(2000));
@Autowired
private RedissonClient redissonClient1;
private RedissonClient redissonClient2;
@Before
public void before() {
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.2.200:6379").setPassword("4J^wxw3@#qjpo0D!");
redissonClient2 = Redisson.create(config);
}
@Test
public void rlockTest1() throws Exception {
RLock rLock = redissonClient1.getLock("test");
try {
rLock.lock();
Thread.sleep(3000);
rLock.unlock();
log.info("==================== success");
} catch (Exception e) {
log.error("", e);
}
}
@Test
public void rlockTest2() throws Exception {
for (int i = 0; i < 1000; i++) {
threadPoolExecutor.submit(new LockTestTaskThread(redissonClient2));
}
while (!threadPoolExecutor.isShutdown()) {
Thread.sleep(1000);
}
}
}
测试用的线程类代码:
...
@Slf4j
public class LockTestTaskThread extends Thread {
private RedissonClient redissonClient;
public LockTestTaskThread(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
@Override
public void run() {
log.info("Thread id {}:", getId());
RLock rLock = redissonClient.getLock("test");
try {
rLock.lock();
log.info("{} lock is:{}", getId(), ObjectMapperUtil.toJsonString(rLock));
Thread.sleep(5000);
log.info("{} task complete", getId());
rLock.unlock();
} catch (Exception e) {
log.error("Thread id {} error", getId(), e);
}
}
}
如果在rlockTest2()方法中使用Spring自动注入的redissionClient1,就会抛出该异常,使用新创建建的redissionClient2则不会!
参考链接: