6.如何使用jedis的线程池

Posted 笨蛋敏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6.如何使用jedis的线程池相关的知识,希望对你有一定的参考价值。

Basic usage example

using Jedis in a multithreaded environment

You shouldn‘t use the same instance from different threads because you‘ll have strange errors. And sometimes creating lots of Jedis instances is not good enough because it means lots of sockets and connections, which leads to strange errors as well. A single Jedis instance is not threadsafe!To avoid these problems, you should use JedisPool, which is a threadsafe pool of network connections. You can use the pool to reliably create several Jedis instances, given you return the Jedis instance to the pool when done. This way you can overcome those strange errors and achieve great performance.

To use it, init a pool:

JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");

You can store the pool somewhere statically, it is thread-safe.

JedisPoolConfig includes a number of helpful Redis-specific connection pooling defaults. JedisPool is based on Commons Pool 2, so you may want to have a look at Commons Pool‘s configuration. Please see http://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/GenericObjectPoolConfig.html for more details.

You use it by:

/// Jedis implements Closable. Hence, the jedis instance will be auto-closed after the last statement.
try (Jedis jedis = pool.getResource()) {
  /// ... do stuff here ... for example
  jedis.set("foo", "bar");
  String foobar = jedis.get("foo");
  jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); 
  Set<String> sose = jedis.zrange("sose", 0, -1);
}
/// ... when closing your application:
pool.destroy();

If you can‘t use try-with-resource, you can still enjoy with Jedis.close().

Jedis jedis = null;
try {
  jedis = pool.getResource();
  /// ... do stuff here ... for example
  jedis.set("foo", "bar");
  String foobar = jedis.get("foo");
  jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); 
  Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
  if (jedis != null) {
    jedis.close();
  }
}
/// ... when closing your application:
pool.destroy();

If Jedis was borrowed from pool, it will be returned to pool with proper method since it already determines there was JedisConnectionException occurred. If Jedis wasn‘t borrowed from pool, it will be disconnected and closed.

 

使用实例:

package com.scut.emos.nziot_base.redis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
 * Created by CMQ on 2017/3/9.
 */
public class JedisPoolHelper {
    private static JedisPool pool = null;
    public static JedisPool getPool(JedisPoolConfig config,String host,int port) {
        if (pool == null) {
            pool = new JedisPool(config, host, port);
        }
        return pool;
    }
    public void destroyPool(){
        pool.destroy();
    }
}
package com.scut.emos.nziot_base;
import com.scut.emos.nziot_base.redis.JedisPoolHelper;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
 * 测试类
 */
public class TestClass {
    private static JedisPool pool = null;
    public TestClass(){
        pool = JedisPoolHelper.getPool(getConfig(),"222.201.145.215",6379);
    }
    public static JedisPoolConfig getConfig(){
        JedisPoolConfig config = new JedisPoolConfig();
        //控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
        //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
        config.setMaxTotal(500);
        //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
        config.setMaxIdle(5);
        //表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
        config.setMaxWaitMillis(1000 * 100);
        //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
        config.setTestOnBorrow(true);
        return config;
    }
    public void sampleUseJedis(){
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            jedis.set("cdaf","dashuaiguola");
            String str = jedis.get("cai");
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    public static void main(String args[]){

        new TestClass().sampleUseJedis();
        // 1. create log
        Logger log = Logger.getLogger(TestClass.class);
        // 2. get log config file
        PropertyConfigurator.configure("log4j.properties");
        // 3. start log
        log.info("sdfa");

    }
}

 

以上是关于6.如何使用jedis的线程池的主要内容,如果未能解决你的问题,请参考以下文章

jedis连接redis

Jedis连接池优化

redis的sentinel主从切换(failover)与Jedis线程池自动重连

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

Redis连接池Lettuce Jedis 区别

Redis的发布订阅+线程池使用实践