JedisPool使用原理和源代码

1,JedisPool的使用

<!-- 连接池的配置信息 --><beanid="jedisConfig"class="redis.clients.jedis.JedisPoolConfig"><!-- 说明一个pool可以有多少个Jedis实例 --><propertyname="maxActive"value="10" /><!-- 最大Idle--><propertyname="maxIdle"value="5" /><!-- 最小Idle --><propertyname="minIdle"value="1" /><!-- 获得一个jedis实例的时候是否检查连接可用性(ping()) --><propertyname="testOnBorrow"value="true" /><!-- return 一个jedis实例给pool时,是否检查连接可用性(ping()) --><propertyname="testOnReturn"value="true" /><!-- idle状态监测用异步线程evict进行检查, --><propertyname="testWhileIdle"value="true" /><!-- 一次最多evict的pool里的jedis实例个数 --><propertyname="numTestsPerEvictionRun"value="10" /><!-- test idle 线程的时间间隔 --><propertyname="timeBetweenEvictionRunsMillis"value="60000" /><!--最大等待wait时间--><propertyname="maxWait"value="3000" /><propertyname="whenExhaustedAction"value="" />
    //WHEN_EXHAUSTED_FAIL = 0; 直接抛出异常throw new NoSuchElementException("Pool exhausted");
    //WHEN_EXHAUSTED_BLOCK = 1;borrowObject()将会阻塞,直到有可用新的或者空闲的object为止,或者如果配置了maxWait,
                            //如果请求阻塞超时,将抛出NoSuchElementException.如果maxWait为负数,请求将会无限制的阻
                            //塞下去,默认配置。
    //WHEN_EXHAUSTED_GROW = 2;borrowObject()将会继续创建新的对象,并返回,因此,pool维护的对像数将超出maxActive;
                            //
</bean>
 
 
public String set(String key, String value) {
    Jedis jedis = null;
    boolean success = true;
    try {
        jedis = this.pool.getResource();
        return jedis.set(key, value);
    }catch (JedisException e) {
        success  = false;
        if(jedis != null){
            pool.returnBrokenResource(jedis);
        }
        throw e;
    }finally{
        if(success && jedis != null){
            this.pool.returnResource(jedis);
        }
    }
}

获取Jedis

pool.getResource();

这个可以直接看Pool的getResource方法,

最终还是GenericObjectPool的borrowObject()方法借用对象

@SuppressWarnings("unchecked")
public T getResource() {
    try {
        return (T) internalPool.borrowObject();
    } catch (Exception e) {
        throw new JedisConnectionException(
                "Could not get a resource from the pool", e);
    }
}

用完归还,调用的是GenericObjectPool的returnObject()方法

pool.returnResource(jedis)
//JedisPool.java
public void returnResource(final BinaryJedis resource) {
    returnResourceObject(resource);
}
//Pool.java
publicvoid returnResourceObject(final Object resource) {
try {
    internalPool.returnObject(resource);
} catch (Exception e) {
    throw new JedisException(
            "Could not return the resource to the pool", e);
}
}

出错,调用的是GenericObjectPool的invalidateObject()方法

最后在JedisFactory的destroyObject()中调用jedis.quit()请求Server关闭连接

pool.returnBrokenResource(jedis)
//JedisPool.java
public void returnBrokenResource(final BinaryJedis resource) {
    returnBrokenResourceObject(resource);
}
//Pool.javaprotectedvoid returnBrokenResourceObject(final Object resource) {
    try {
        //失效
        internalPool.invalidateObject(resource);
    } catch (Exception e) {
        thrownew JedisException(
                "Could not return the resource to the pool", e);
    }
}
//GenericObjectPool
publicvoid invalidateObject(Object obj)
throws Exception
{
try
{
  if (this._factory != null)
    this._factory.destroyObject(obj);
}
finally {
  synchronized (this) {
    this._numActive -= 1;
    allocate();
  }
}
}
//JedisFactory
publicvoid destroyObject(final Object obj) throws Exception {
    if (obj instanceof Jedis) {
        final Jedis jedis = (Jedis) obj;
        if (jedis.isConnected()) {
            try {
                try {
                    jedis.quit();
                } catch (Exception e) {
                }
                jedis.disconnect();
            } catch (Exception e) {

            }
        }
    }
}


JedisPool源代码

package redis.clients.jedis;

import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config;

import redis.clients.util.Pool;

publicclassJedisPoolextendsPool<Jedis> {public JedisPool(final Config poolConfig, final String host) {
        this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
    }

    public JedisPool(String host, int port) {
        this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
    }

    public JedisPool(final String host) {
        this(host, Protocol.DEFAULT_PORT);
    }

    public JedisPool(final Config poolConfig, final String host, int port,
            int timeout, final String password) {
        this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE);
    }

    public JedisPool(final Config poolConfig, final String host, finalint port) {
        this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
    }

    public JedisPool(final Config poolConfig, final String host, finalint port, finalint timeout) {
        this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE);
    }

    public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password,
                     finalint database) {
        super(poolConfig, new JedisFactory(host, port, timeout, password, database));
    }

    publicvoid returnBrokenResource(final BinaryJedis resource) {
        returnBrokenResourceObject(resource);
    }

    publicvoid returnResource(final BinaryJedis resource) {
        returnResourceObject(resource);
    }

    /**
     * PoolableObjectFactory custom impl.
     */privatestaticclassJedisFactoryextendsBasePoolableObjectFactory {privatefinal String host;
        privatefinalint port;
        privatefinalint timeout;
        privatefinal String password;
        privatefinalint database;

        public JedisFactory(final String host, finalint port,
                finalint timeout, final String password, finalint database) {
            super();
            this.host = host;
            this.port = port;
            this.timeout = timeout;
            this.password = password;
            this.database = database;
        }

        public Object makeObject() throws Exception {
            final Jedis jedis = new Jedis(this.host, this.port, this.timeout);

            jedis.connect();
            if (null != this.password) {
                jedis.auth(this.password);
            }
            if( database != 0 ) {
                jedis.select(database);
            }

            return jedis;
        }

        publicvoid destroyObject(final Object obj) throws Exception {
            if (obj instanceof Jedis) {
                final Jedis jedis = (Jedis) obj;
                if (jedis.isConnected()) {
                    try {
                        try {
                            jedis.quit();
                        } catch (Exception e) {
                        }
                        jedis.disconnect();
                    } catch (Exception e) {

                    }
                }
            }
        }

        publicboolean validateObject(final Object obj) {
            if (obj instanceof Jedis) {
                final Jedis jedis = (Jedis) obj;
                try {
                    return jedis.isConnected();/* && jedis.ping().equals("PONG");*/
                } catch (final Exception e) {
                    returnfalse;
                }
            } else {
                returnfalse;
            }
        }
    }
}

其中JedisFactory继承自BasePoolableObjectFactory,只实现了3个方法

makeObject(),连接,new Socket()

destroyObject()--断开连接,

validateObject()--ping




Pool源代码

package redis.clients.util;

import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisException;

publicabstractclassPool<T> {privatefinal GenericObjectPool internalPool;

    public Pool(final GenericObjectPool.Config poolConfig,
            PoolableObjectFactory factory) {
        this.internalPool = new GenericObjectPool(factory, poolConfig);
    }

    @SuppressWarnings("unchecked")
    public T getResource() {
        try {
            return (T) internalPool.borrowObject();
        } catch (Exception e) {
            thrownew JedisConnectionException(
                    "Could not get a resource from the pool", e);
        }
    }

    publicvoid returnResourceObject(final Object resource) {
        try {
            internalPool.returnObject(resource);
        } catch (Exception e) {
            thrownew JedisException(
                    "Could not return the resource to the pool", e);
        }
    }

    publicvoid returnBrokenResource(final T resource) {
        returnBrokenResourceObject(resource);
    }

    publicvoid returnResource(final T resource) {
        returnResourceObject(resource);
    }

    protectedvoid returnBrokenResourceObject(final Object resource) {
        try {
            //失效
            internalPool.invalidateObject(resource);
        } catch (Exception e) {
            thrownew JedisException(
                    "Could not return the resource to the pool", e);
        }
    }

    publicvoid destroy() {
        try {
            internalPool.close();
        } catch (Exception e) {
            thrownew JedisException("Could not destroy the pool", e);
        }
    }
}

JedisPoolConfig源代码

publicclassJedisPoolConfigextendsConfig {public JedisPoolConfig() {
        // defaults to make your life with connection pool easier :)
        setTestWhileIdle(true);
        setMinEvictableIdleTimeMillis(60000);
        setTimeBetweenEvictionRunsMillis(30000);
        setNumTestsPerEvictionRun(-1);
    }

    publicint getMaxIdle() {
        return maxIdle;
    }

    publicvoid setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    publicint getMinIdle() {
        return minIdle;
    }

    publicvoid setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    publicint getMaxActive() {
        return maxActive;
    }

    publicvoid setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    publiclong getMaxWait() {
        return maxWait;
    }

    publicvoid setMaxWait(long maxWait) {
        this.maxWait = maxWait;
    }

    publicbyte getWhenExhaustedAction() {
        return whenExhaustedAction;
    }

    publicvoid setWhenExhaustedAction(byte whenExhaustedAction) {
        this.whenExhaustedAction = whenExhaustedAction;
    }

    publicboolean isTestOnBorrow() {
        return testOnBorrow;
    }

    publicvoid setTestOnBorrow(boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    publicboolean isTestOnReturn() {
        return testOnReturn;
    }

    publicvoid setTestOnReturn(boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }

    publicboolean isTestWhileIdle() {
        return testWhileIdle;
    }

    publicvoid setTestWhileIdle(boolean testWhileIdle) {
        this.testWhileIdle = testWhileIdle;
    }

    publiclong getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    publicvoid setTimeBetweenEvictionRunsMillis(
            long timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    publicint getNumTestsPerEvictionRun() {
        return numTestsPerEvictionRun;
    }

    publicvoid setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }

    publiclong getMinEvictableIdleTimeMillis() {
        return minEvictableIdleTimeMillis;
    }

    publicvoid setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    publiclong getSoftMinEvictableIdleTimeMillis() {
        return softMinEvictableIdleTimeMillis;
    }

    publicvoid setSoftMinEvictableIdleTimeMillis(
            long softMinEvictableIdleTimeMillis) {
        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
    }

}

 

时间: 2025-01-31 06:48:18

JedisPool使用原理和源代码的相关文章

Udp打洞原理和源代码。

所谓udp打洞就是指客户端A通过udp协议向服务器发送数据包,服务器收到后,获取数据包,并且 可获取客户端A地址和端口号.同样在客户端B发送给服务器udp数据包后,服务器同样在收到B发送过来 的数据包后获取B的地址和端口号,将A和B的地址与端口号分别发送给对方,这样双方可以继续用UDP协议 通信.这么做有什么用呢?因为对于一些应用或者需求,需要两个客户端临时做一些通信,而这种通信 不需要建立tcp就可以完成,所以才去udp打洞. 下面附上测试代码: 头文件 // udphole.cpp : 定义

Linux下二进制包和源代码包的区分

主要提供三种格式的mysql包:rpm格式.二进制格式.源码格式:(tar打包,gz压缩) rpm格式: libjpeg-devel-6b-33.x86_64.rpm       #rpm格式很好区分, 二进制包: mysql-3.23.58-pc-linux-i686.tar.gz   #二进制格式的包名字很长,有版本号.适应平台.适应的硬件类型等,格式:mysql-<版本>-<OS>-tar.gz 源码包:    php-5.2.14.tar.gz              

Dubbo原理和源码解析之服务暴露

一.框架设计 在官方<Dubbo 用户指南>架构部分,给出了服务调用的整体架构和流程: 另外,在官方<Dubbo 开发指南>框架设计部分,给出了整体设计: 以及暴露服务时序图: 本文将根据以上几张图,分析服务暴露的实现原理,并进行详细的代码跟踪与解析. 二.原理和源码解析 2.1 标签解析 从文章<Dubbo原理和源码解析之标签解析>中我们知道,<dubbo:service> 标签会被解析成 ServiceBean. ServiceBean 实现了 Init

[转]计算机视觉、机器学习相关领域论文和源代码大集合

计算机视觉.机器学习相关领域论文和源代码大集合--持续更新…… [email protected] http://blog.csdn.net/zouxy09 注:下面有project网站的大部分都有paper和相应的code.Code一般是C/C++或者Matlab代码. 最近一次更新:2013-3-17 一.特征提取Feature Extraction: ·         SIFT [1] [Demo program][SIFT Library] [VLFeat] ·         PCA

Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序)

1. TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序) (1)Student.java: 1 package cn.itcast_07; 2 3 public class Student { 4 private String name; 5 private int age; 6 7 public Student() { 8 super(); 9 } 10 11 public Student(String name, int age) { 12 super(); 13 thi

android中RadioGroup、RadioButton、Spinner、EditText用法详解(含示例截图和源代码)

为了保护版权.尊重原创,转载请注明出处:http://blog.csdn.net/u013149325/article/details/43237757,谢谢! 今天在项目中用到了android中常用的RadioGroup.RadioButton.Spinner.EditText等控件,在此介绍一下它们的用法,希望对需要的朋友有帮助. 一.RadioGroup和RadioButton的使用 RadioButton就是我们常见的单选按钮,一个RadioGroup可以包含多个单选按钮,但是每次只能选

从原理到代码:大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社

从原理到代码:大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社 PPT链接: https://pan.baidu.com/s/1i5Jrr1N 视频链接: https://v.qq.com/x/page/n0386utnrb0.html?start=492

flume原理及代码实现

转载标明出处:http://www.cnblogs.com/adealjason/p/6240122.html 最近想玩一下流计算,先看了flume的实现原理及源码 源码可以去apache 官网下载 下面整理下flume的原理及代码实现: flume是一个实时数据收集工具,hadoop的生态圈之一,主要用来在分布式环境下各服务器节点做数据收集,然后汇总到统一的数据存储平台,flume支持多种部署架构模式,单点agent部署,分层架构模式部署,如通过一个负载均衡agent将收集的数据分发到各个子a

android widget 开发实例 : 桌面便签程序的实现具体解释和源代码 (上)

如有错漏请不吝拍砖指正,转载请注明出处,很感谢 桌面便签软件是android上经常使用软件的一种,比方比較早的Sticky Note,就曾很流行, Sticky Note的介绍能够參见 http://www.tompda.com/c/article/11778/ 而实际上使用android平台对widget开发的支持,桌面便签类软件是很易于开发的. 本文通过逐步实现一个简单的桌面便签软件,和大家分享进行widget开发的过程和方法. 1.MyNote的终于实现效果 为了提起大家阅读本文的兴趣,先