jedis:连接池(JedisPool)使用示例

Jedis实例不是线程安全的,所以不可以多个线程共用一个Jedis实例,但是创建太多的实现也不好因为这意味着会建立很多sokcet连接。
JedisPool是一个线程安全的网络连接池。可以用JedisPool创建一些可靠Jedis实例,可以从池中获取Jedis实例,使用完后再把Jedis实例还回JedisPool。这种方式可以避免创建大量socket连接并且会实现高效的性能.

JedisPool初始化

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 设置最大10个连接
        jedisPoolConfig.setMaxTotal(10);
        pool = new JedisPool(jedisPoolConfig, "localhost");

使用JedisPool

1.JedisPool#getResource()方法从连接池中取得一个Jedis实例,
2.使用Jedis实例进行正常的数据操作
3.Jedis实例使用完后要把它再放回连接池。

资源释放

关于如何将使用完后的Jedis实例还回连接池,网上看到的大部分文章都是建议用JedisPool#returnResource方法,这些文章大多是3,4年前的文章

jedis官网:https://github.com/xetorthio/jedis

而当我使用jedis时,jedis的最新版本已经到了2.9(我使用的是2.8.2)。
在jedis2.8.2中已经将JedisPool#returnResource方法废弃了,并明确说明这个方法的功能由Jedis.close()方法代替。

void redis.clients.jedis.JedisPool.returnResource(Jedis resource)
@Override
@Deprecated
不推荐. starting from Jedis 3.0 this method will not be exposed. Resource cleanup should be done using @see redis.clients.jedis.Jedis.close()
本文作者注:从Jedis 3.0开始这个方法将不再暴露给外部(public),资源清除应该调用用Jedis.close()方法
覆盖: Pool 中的 returnResource(...)
参数:resource 

如果进一步查看Jedis#close()方法的源码,会发现,close()方法最终依然是调用 JedisPool#returnResource方法。
可以看到,当使用JedisPool时,close方法并没有真的执行client.close方法,只是将它还给JedisPool连接池,以供下次使用。

  @Override
  public void close() {
    if (dataSource != null) {
      // dataSource 即为 JedisPool实例,
      if (client.isBroken()) {
        // 调用 JedisPool#returnBrokenResource方法
        this.dataSource.returnBrokenResource(this);
      } else {
      // 调用 JedisPool#returnResource 方法
        this.dataSource.returnResource(this);
      }
    } else {
      client.close();
    }
  }

所以正确使用并释放连接池资源的方式如下:

        Jedis jedis = null;
        try{
            // 从连接池获取一个Jedis实例
            jedis = pool.getResource();
            //设置 redis 字符串数据 SET 10km blog.csdn.net/10km
            jedis.set("10km", "blog.csdn.net/10km");
            // 获取存储的数据并输出
            System.out.println("redis 存储的字符串为: "+ jedis.get("10km"));           
        }finally{
            if(null != jedis)
                jedis.close(); // 释放资源还给连接池
        }

完整Junit测试代码

package net.gdface.facelog;

import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestRedis {
	private JedisPool pool;
	/**
	 * 初始化连接池
	 */
	@Before
	public void init() {
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
	    jedisPoolConfig.setMaxTotal(10);
	    pool = new JedisPool(jedisPoolConfig, "localhost");
        System.out.println("连接池初始化成功");
	}
    @Test
    public void testPing(){
    	// Jedis 实现了java.lang.AutoCloseable接口,所以这里可以用java 1.7 try-with-resources语法自动完成close
    	try(Jedis jedis = pool.getResource()){
            //查看服务是否运行 PING
            System.out.println("服务正在运行: "+jedis.ping());
    	}
    }
    @Test
    public void testString(){
    	try(Jedis jedis = pool.getResource()){
            //设置 redis 字符串数据 SET 10km blog.csdn.net/10km
            jedis.set("10km", "blog.csdn.net/10km");
            // 获取存储的数据并输出
            System.out.println("redis 存储的字符串为: "+ jedis.get("10km"));    		
    	}
    }
    @Test
	public void testList() {
		try (Jedis jedis = pool.getResource()) {
			// 选择数据库:  SELECT 2
			jedis.select(2);
			// 存储数据到列表中
			// LPUSH 
			jedis.lpush("phone_list", "Apple");
			jedis.lpush("phone_list", "Huawei");
			jedis.lpush("phone_list", "XiaoMi");

			// 获取存储的数据并输出: LRANGE phone_list 0 2
			List<String> list = jedis.lrange("phone_list", 0, 2);
			for (int i = 0; i < list.size(); i++) {
				System.out.println("phone_list 列表项为: " + list.get(i));
			}
		}
	}
    /**
     * 程序关闭时,需要调用关闭方法
     */
    @After
    public void end(){    	
    	if(null != pool){
    		pool.destroy();
    		System.out.println("连接池关闭");
    	}
    		
    }
}

参考资料

[《Java中使用Jedis操作Redis》]1
[《JedisPool介绍》]2


  1. http://www.cnblogs.com/liuling/p/2014-4-19-04.html ↩︎

  2. https://my.oschina.net/XYleung/blog/101027 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值