Redis connection pool reads data concurrently, and connection pool cannot recycle connections.

I wrote a redis client myself. When testing concurrently, I found that the acquired redis connection could not be returned to the connection pool

this is the unit test class

public class RedisTest {

    private static final ExecutorService executorService = Executors.newFixedThreadPool(1000);
    private static CyclicBarrier c = new CyclicBarrier(200);


    @Test
    public void simpleTest() {
        System.out.println(RedisUtil.get("yany_test"));
    }

    @Test
    public void test() throws Exception {
        for (int i = 0; i < 300; iPP) {

            executorService.submit(() -> {
//                try {
//                    c.await();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }

                System.out.println("num  end end====" + c.getNumberWaiting() + "   " + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
                System.out.println("id =====>:" + Thread.currentThread().getId() + " " + Thread.currentThread().getName() + " " + RedisUtil.get("yany_test"));

            });
        }
        Thread.sleep(200000);
    }
}

basic configuration

jedis.pool.maxActive=20
jedis.pool.maxIdle=5
jedis.pool.maxWait=100

Factory class of the connection

public class RedisFactory {

    private static JedisPool jedisPool = null;
    //redis

    static {
        try {
            Properties props = new Properties();
            //
            props.load(RedisFactory.class.getClassLoader().getResourceAsStream("redis-config.properties"));
            // jedis
            JedisPoolConfig config = new JedisPoolConfig();
            // 
            config.setMaxTotal(Integer.valueOf(props.getProperty("jedis.pool.maxActive")));
            config.setMaxIdle(Integer.valueOf(props.getProperty("jedis.pool.maxIdle")));
            config.setMaxWaitMillis(Long.valueOf(props.getProperty("jedis.pool.maxWait")));
            config.setTestOnBorrow(Boolean.valueOf(props.getProperty("jedis.pool.testOnBorrow")));
            config.setTestOnReturn(Boolean.valueOf(props.getProperty("jedis.pool.testOnReturn")));
            // jedis
            jedisPool = new JedisPool(config, props.getProperty("redis.ip"),
                    Integer.valueOf(props.getProperty("redis.port")),
                    Integer.valueOf(props.getProperty("redis.timeout")),
                    props.getProperty("redis.passWord"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     *
     * @return Jedis
     */
    public static Jedis getConn() {
        //Redis
        return jedisPool.getResource();
    }

    //close
    public static void closeConn(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    //
    public static void closePool() {
        if (jedisPool != null) {
            jedisPool.close();
        }
    }

    public static JedisPool getJedisPool() {
        return jedisPool;
    }
}

encapsulated operation class


public class RedisUtil {

    public static String get(String key) {
        Jedis jedis = null;
        try {
            jedis = RedisFactory.getConn();
            return jedis.get(key);
        } finally {
            RedisFactory.closeConn(jedis);
        }
    }
}

this is the output: only 20 threads can read it after the concurrency, while other threads wait all the time and do not report a timeout

.

in theory, should not, can all threads read it? When a thread finishes executing, it returns the connection and asks why there is not enough connection.

Oct.11,2021

according to the subject's code for a while, can read the value, look at the picture in the question, thread 265 has also read the value, do not know how to judge only 20 threads can read , and all threads will block, this is because you used FixedThreadPool , but did not show to close it, FixedThreadPool core thread does not have a timeout strategy, so it will not be closed automatically. When he finishes one task, he will block and wait for the next task. If there is no next task, he will always block. This is why other threads have been waiting and have not reported a timeout . The subject can switch to another thread pool or manually close it (call the shutdown method after all threads have finished executing).

Menu