错误信息:
IllegalStateException: Invalidated object not currently part of this pool
一、问题描述
前些天用多线程执行操作测试验证vanyar-redis连接池,应用是刚重启的状态,执行操作是,开启10个线程同时执行10000次操作。
如下:
执行操作完毕后发现控制台输出9个下面错误信息:
该错误大致意思是说:不能将redis连接放回池内,放回连接池的对象是无效的对象。在网上查了很多同类错误,都说是进行了两次returnResource释放连接资源造成的,因为第一次return成功以后,第二次return就会报上面这个错误。但是显然,我翻遍了代码并没有两次调用returnResource。
查看redis服务端的连接数详细信息如下,前9个连接,idle=453,空闲了453秒了,依然没有释放,而连接池设置的是空闲60秒就会被释放,明显发生异常了。
初步怀疑是多线程执行redis操作,初始化redis连接池有问题。于是重启应用,先执行单线程redis操作,再执行多线程redis操作,没有发生上面的问题。redis服务端连接均能正常释放。由此得出结论,当线程池在未初始化的时候,由于多线程同时执行redis连接池初始化工作引起的问题。
看代码(RedisJedisPool未优化之前):当10个线程同时请求redis连接资源时,10个线程都发现连接池为空(因为创建连接池相比创建线程比较耗时),这时10个线程都各自初始化成功一个连接池,并从中取得redis连接,并执行了redis操作。执行完毕,returnResource的时候,由于此时pool变量的引用是最后一个线程初始化的连接池,前面9个线程获得的redis连接并不属于最后一个连接池的资源,所以抛错:IllegalStateException: Invalidated object not currently part of this pool
二、报错原因分析
线程1 : 创建redis连接池1 : 获得redis连接1
线程2 : 创建redis连接池2 : 获得redis连接2
线程3 : 创建redis连接池3 : 获得redis连接3
……
线程8 : 创建redis连接池8 : 获得redis连接8
线程9 : 创建redis连接池9 : 获得redis连接9
线程10 : 创建redis连接池10 : 获得redis连接10
全局变量pool引用 指向 redis连接池10
当线程1-9 把redis连接1-9 归还给pool-redis连接池