jedis多线程异常

多线程下使用jedis会报一些奇怪的错误:

redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: t
    at redis.clients.jedis.Protocol.process(Protocol.java:72)
    at redis.clients.jedis.Protocol.read(Protocol.java:123)
    at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:183)
    at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:165)
    at redis.clients.jedis.Jedis.hgetAll(Jedis.java:863)
redis.clients.jedis.exceptions.JedisConnectionException: Unknown reply: s
    at redis.clients.jedis.Protocol.process(Protocol.java:72)
    at redis.clients.jedis.Protocol.read(Protocol.java:123)
    at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:183)
    at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:165)
    at redis.clients.jedis.Jedis.hgetAll(Jedis.java:863)
java.lang.ClassCastException: [B cannot be cast to java.util.List
    at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:183)
    at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:165)
    at redis.clients.jedis.Jedis.hgetAll(Jedis.java:863)

jedis并不是线程安全的,于是在程序中改为每个线程只使用一个jedis实例。

较好的解决办法是使用JedisPool,见官方文档:https://github.com/xetorthio/jedis/wiki/Getting-started

先初始化一个池,可以设置一些参数,如setMaxActive,setMaxIdle等

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

然后就可以从池中取出一个实例:

Jedis jedis = pool.getResource();
try {
  /// ... 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 {
  /// ... it's important to return the Jedis instance to the pool once you've finished using it
  pool.returnResource(jedis);
}
/// ... when closing your application:
pool.destroy();

用完要记得放回池,不用了需要销毁。

发表评论

电子邮件地址不会被公开。 必填项已用*标注