问题的原因是因为redis释放了两次,是由于我们使用不当造成的,先看一下错误的写法:
JedisPool pool = new JedisPool(new JedisPoolConfig(), host, port, time, password);
Jedis jedis = pool.getResource();
try {
jedis.set("key", "hello");
} finally {
pool.returnResource(jedis);
}
直接释放的是线程池,而线程池释放的时候又会去调用jedis.close,所以会造成二次释放
// redis.clients.jedis.JedisFactory#destroyObject
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.isConnected()) {
try {
// need a proper test, probably with mock
if (!jedis.isBroken()) {
jedis.quit();
}
} catch (Exception e) {
logger.warn("Error while QUIT", e);
}
try {
jedis.close();
} catch (Exception e) {
logger.warn("Error while close", e);
}
}
}
// redis.clients.jedis.Jedis#close
public void close() {
if (dataSource != null) {
JedisPoolAbstract pool = this.dataSource;
this.dataSource = null;
// 二次释放
if (isBroken()) {
pool.returnBrokenResource(this);
} else {
pool.returnResource(this);
}
} else {
super.close();
}
}
正确的使用方法应该是,直接调用jedis.close()方法
try {
jedis.set("key", "hello");
} finally {
jedis.close();
}