Почему один экземпляр Jedis не является потокобезопасным?

https://github.com/xetorthio/jedis/wiki/Началоработы

использование Jedis в многопоточной среде

Вы не должны использовать один и тот же экземпляр из разных потоков, потому что у вас будут странные ошибки. И иногда создание множества экземпляров Jedis недостаточно, потому что это означает множество сокетов и соединений, что также приводит к странным ошибкам.

Один экземпляр Jedis не является потокобезопасным

! Чтобы избежать этих проблем, вы должны использовать JedisPool, который представляет собой потокобезопасный пул сетевых подключений. Вы можете использовать пул для надежного создания нескольких экземпляров Jedis, если вы вернете экземпляр Jedis в пул, когда закончите. Таким образом, вы сможете преодолеть эти странные ошибки и добиться отличной производительности.

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

Я хочу знать, почему? Кто-нибудь может мне помочь


person BoTaoLiu    schedule 07.05.2015    source источник


Ответы (1)


Один экземпляр 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 и обеспечивайте безопасность потоков.

person medvedev1088    schedule 07.05.2015
comment
Это должно произойти, когда мы используем один и тот же экземпляр Jedis во всех потоках. Разве мы не можем инициализировать разные экземпляры Jedis для разных потоков? - person Aashish Katta; 06.08.2018
comment
@medvedev jedispool по-прежнему ограничивал бы его одним исходящим запросом и одним ответом. Есть ли способ обойти это ограничение? теоретически? Redisson использует netty и каналы для этой цели, как они утверждают. Я не уверен, что Redis может отправлять несколько одновременных запросов из одного и того же соединения. это возможно в теории? способ реализации jedis не будет работать, поскольку он отправляет команду, а затем глобально ожидает входного потока из соединения, что означает, что если отправлены два запроса, ответ может быть сочетанием двух. это ограничение джедаев или редисов как таковых? - person mmm; 05.09.2020