package JedisTest;
import org.apache.commons.lang.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Jedis工具类
* @author lanchunqiu
*
*/
public class JedisUtil {
private static int PORT = 6379;
/**
* 可用连接实例的最大数目,如果不设默认为8,;如果赋值为-1表示不限制;如果pool已经分配了MAX_ACTIVE个jedis实例,则此时pool的状态为exhausted(耗尽)
*/
private static int MAX_ACTIVE = 500;
/**
* 控制一个pool最多有多少个状态为idle(空闲)的jedis实例,不设默认值为8
*/
private static int MAX_IDLE = 10;
/**
* 控制一个pool最少有多少个状态为空闲的jedis实例
*/
private static int MIN_IDLE = 100;
/**
* 在borrow一个jedis实例时,是否提前进行validate(验证)操作,如果为true,则得到的jedis实例都是可用的
*/
private static boolean TEST_ON_BOOROW = true;
/**
* 在将连接放回池中前,自动检验连接是否有效
*/
private static boolean TEST_ON_RETURN = true;
/**
* 自动测试池中的空闲连接是否都是可用连接
*/
private static boolean TEST_WHILE_IDLE = true;
/**
* 等待一个可用连接的最大时间,单位毫秒,默认值为-1,表示用不超时;如果超过等待时间,则直接抛出JedisConnectionException
*/
private static int MAX_WAIT = 60000;
/**
* 每次释放连接的最大数目
*/
private static int NUM_TESTS_PER_EVICTION_RUN = 10;
/**
* 释放连接的扫描间隔(毫秒)
*/
private static int TIME_BETWEEN_EVICTION_RUNS_MILLIS = 10;
/**
* 连接空闲多久后释放(毫秒), 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放
*/
private static int SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS= 100;
private static int TIMEOUT = 100000;
private static JedisPool jedisPool = null;
private static JedisUtil jedisUtil = null;
protected JedisUtil(){
try{
System.out.println("初始化redis缓存!");
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxWaitMillis(MAX_WAIT);
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMinIdle(MIN_IDLE);
config.setTestOnBorrow(TEST_ON_BOOROW);
config.setTestOnReturn(TEST_ON_RETURN);
config.setTestWhileIdle(TEST_WHILE_IDLE);
config.setNumTestsPerEvictionRun(NUM_TESTS_PER_EVICTION_RUN);
config.setTimeBetweenEvictionRunsMillis(TIME_BETWEEN_EVICTION_RUNS_MILLIS);
config.setMinEvictableIdleTimeMillis(SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS);
jedisPool = new JedisPool(config, "127.0.0.1",PORT,TIMEOUT,"asopa_redis");
//jedisPool = new JedisPool(config, "127.0.0.1",PORT);
}catch(Exception e){
System.out.println("初始化JedisPool异常:" + e);
jedisPool = null;
}
}
public static synchronized JedisUtil getInstance(){
if(null == jedisUtil){
jedisUtil = new JedisUtil();
}
return jedisUtil;
}
/**
* 设置 String
* @param key
* @param value
*/
public static void setString(String key ,String value){
Jedis jedis = null;
try {
System.out.println("【存】可用连接数"+jedisPool.getNumActive());
jedis = jedisPool.getResource();
value = StringUtils.isEmpty(value) ? "" : value;
jedis.set(key,value);
} catch (Exception e) {
System.out.println("Set key error : " + e);
} finally{
jedisPool.returnResource(jedis);//注意:每次使用完jedis时一定要释放
}
}
/**
* 取值
* @param key
* @return
*/
public static String get(String key){
Jedis jedis = null;
try{
System.out.println("【取】可用连接数"+jedisPool.getNumActive());
jedis = jedisPool.getResource();
return jedis.get(key);
}
catch(Exception e){
System.out.println("从缓存中取值失败:"+e.getMessage());
return null;
} finally{
jedisPool.returnResource(jedis);
}
}
}
2.JedisTestThread 线程类
package JedisTest;
/**
*
* @author lanchunqiu
*
*/
public class JedisTestThread extends Thread{
private JedisUtil jedisUtil = null;
public JedisTestThread(int i,JedisUtil jedisUtil){
System.out.println("=======线程"+i+"========"+jedisUtil.hashCode());
this.jedisUtil = jedisUtil;
}
public void run(){
jedisUtil.setString("foo1", "foo1");
System.out.println(jedisUtil.get("foo1"));
}
}
3.测试类:开启了1000个线程,如果想要启动更多的线程,就需要调整MAX_ACTIVE 参数值,开启1000个线程时,我设置的MAX_ACTIVE =500
package JedisTest;
import java.io.IOException;
/**
*
* @author lanchunqiu
*
*/
public class JedisTest {
public static void main(String[] args) throws IOException {
JedisUtil jedisUtil = JedisUtil.getInstance();
for (int i=0;i<1000;i++){
JedisTestThread thread1 = new JedisTestThread(i+1,jedisUtil);
thread1.start();
}
}
}
4.测试结果:就算连接数为0时也没出现异常,占用的连接会很快释放。
还请大牛多指教!
5.使用的jar包:
(1)jedis-2.8.0.jar
(2)commons-pool2-2.4.2.jar
(3)commons-lang-2.4.jar