为什么单个Jedis实例不是线程安全的?

时间:2015-05-07 16:58:22

标签: redis thread-safety pool jedis

https://github.com/xetorthio/jedis/wiki/Getting-started

在多线程环境中使用Jedis

您不应该使用来自不同线程的相同实例,因为您会遇到奇怪的错误。有时创建大量的Jedis实例并不够好,因为它意味着许多套接字和连接,这也会导致奇怪的错误。

  

单个Jedis实例不是线程安全的

!要避免这些问题,您应该使用JedisPool,它是一个线程安全的网络连接池。您可以使用池可靠地创建多个Jedis实例,因为您在完成后将Jedis实例返回到池中。通过这种方式,您可以克服这些奇怪的错误并获得出色的性能。

=============================================== ==

我想知道为什么?任何人都可以帮助我

1 个答案:

答案 0 :(得分:3)

单个Jedis实例不是线程安全的,因为它是以这种方式实现的。这是图书馆作者做出的决定。

您可以查看BinaryJedis的源代码,这是一种超级类型的Jedis https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/BinaryJedis.java

例如这些行:

public Transaction multi() {
    client.multi();
    client.getOne(); // expected OK
    transaction = new Transaction(client);
    return transaction;
}

正如您所看到的,使用Jedis实例为所有线程共享事务字段并在此方法中初始化。稍后此事务可用于其他方法。想象一下,两个线程同时执行事务操作。结果可能是由一个线程创建的事务被另一个线程无意中访问。在这种情况下,事务字段是未同步的共享状态访问。这使得Jedis非线程安全。

作者决定使Jedis非线程安全和JedisPool线程安全的原因可能是为客户端提供灵活性,这样如果您有单线程环境,您可以使用Jedis并获得更好的性能,或者如果您有多线程环境你可以使用JedisPool并获得线程安全。