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

BoT*_*Liu 5 pool thread-safety redis jedis

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

在多线程环境中使用 Jedis

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

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

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

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

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

med*_*088 6

单个 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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