首先我们如果每次使用缓存都生成一个Jedis对象的话,这样意味着会建立很多的socket连接,造成系统资源被不可控调用,甚至会导致奇怪的错误发生。如果使用单例模式,在线程安全模式下适应不了高并发的需求,非线程安全模式有可能会出现与时间相关的错误。因此,为了避免这些问题,引入了池的概念 JedisPool。JedisPool是一个线程安全的网络连接池,我们可以通过JedisPool创建和管理Jedis实例,这样可以有效地解决以上问题以实现系统的高性能。
?
public class JedisPoolUtil{
private JedisPoolUtil(){}
public static JedisPool getJedisPoolInstance(){
if(null == jedisPool){
synchronized(JedisPoolUtil.class){
if(null == jedisPool){
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(1000);
poolConfig.setMaxIdle(32);
poolConfig.setMaxWait(1000*100);
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig,127.0.0.1",6379");
}
}
}
return jedisPool;
}
public static release(JedisPool jedisPool,Jedis jedis){
if(null != jedis){
jedisPool.returnResourceObject(jedis);
}
}
}
其中使用了双端检索的单例模式,保证了线程安全的高效检查。
release方法是为了把不用的连接资源放回连接池中。
?
maxActive:控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted。
maxIdle:控制一个pool最多有多少个状态为idle(空闲)的jedis实例;
maxWait:表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛JedisConnectionException;
testOnBorrow:获得一个jedis实例的时候是否检查连接可用性(ping());如果为true,则得到的jedis实例均是可用的;