代码之家  ›  专栏  ›  技术社区  ›  Tom Taylor

Jedis池已初始化多次

  •  1
  • Tom Taylor  · 技术社区  · 6 年前

    我在用 redis 在…的帮助下 jedis 客户端。在此处附加键值set/get的代码段。我在这儿等我的 jedisPool 只初始化一次,但多次初始化。不知道我哪里出错了。用它挠我的头好几天。我不知道它为什么要进行多重初始化。

    //$Id$
    package experiments.with.truth;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    public class RedisClientUtil {
    
        private static JedisPool pool;                  //I persume the deafult value initialised in my static variable would be null
        static int maxActiveConnections = 8;
        static int maxWaitInMillis = 2000;
        static String host = "127.0.0.1";
        static int port = 6379;
        static int REDIS_DB = 1;
    
        public static void initRedisClient() throws Exception {
            try {
                Class classObj = Class.forName("redis.clients.jedis.JedisPool");
                if (classObj != null && pool == null) {
                    JedisPoolConfig jedisConfig = new JedisPoolConfig();
                    jedisConfig.setMaxTotal(maxActiveConnections);
                    jedisConfig.setMaxWaitMillis(maxWaitInMillis);
                    pool = new JedisPool(jedisConfig, host, port);      
    
                    System.out.println("Pool initialised successfully !");
                }
            } catch(ClassNotFoundException ex) {
                System.out.println("Couldn't initialize redis due to unavailability of jedis jar in your machine. Exception : " + ex);
            }
        }
        public Jedis getJedisConnection() {
            if(pool == null) {
                initRedisClient();
            }
            return pool.getResource();
        }
        private static void returnJedis(Jedis jedis) {
            try {
                pool.returnResource(jedis);
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        }
        public static String getValue(String key) throws Exception{
            Jedis jedisCon = null; 
            try {
                jedisCon = getJedisConnection();
                jedisCon.select(REDIS_DB);
    
                String val = jedisCon.get(key); 
                return val;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (jedisCon != null) {
                    returnJedis(jedisCon);
                }
            }
            return null;
        }
        public void addValueToRedis(String key, String value) {
            Jedis jedisCon = null; 
            try {
                jedisCon = getJedisConnection();
                jedisCon.select(REDIS_DB);
    
                jedisCon.set(key, value); 
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (jedisCon != null) {
                    returnJedis(jedisCon);
                }
            }
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println("Value : " + getValue("a"));
            System.out.println("Value : " + getValue("b"));
            System.out.println("Value : " + getValue("c"));
        }
    }
    

    我可以看到这个调试日志 Pool initialised successfully 我的程序运行多次。有人能帮我找到这个漏洞吗?或者我如何通过在整个程序中只初始化一次就可以使它变得更好(或者使它按预期的方式运行)。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Imaskar    6 年前

    看起来像一个基本的多线程案例。你的应用程序在短时间内需要5个连接。所有人都看到pool==null,然后继续初始化它。

    简易解决方案: public static synchronized void initRedisClient() throws Exception {

    更新 private static volatile JedisPool pool; 否则,您可能会得到空指针异常。

    对于更复杂和性能更高的解决方案,在Java中搜索“高效懒惰的单身者”,这很可能会引导你。 Enum 解决方案。