Проще говоря, может ли один экземпляр javax.crypto.Cipher
(например, Cipher.getInstance("RSA")
) использоваться из нескольких потоков или мне нужно вставить несколько из них в ThreadLocal
(в моем случае)?
Является ли шифр потокобезопасным?
Ответ 1
Нет, это не так. Экземпляр - состояние. Поэтому вам нужно сохранить его threadlocal или получить новый экземпляр при каждом вызове шифрования/дешифрования или обернуть его в блок synchronized(cipher)
.
Threadsafety обычно явно, упомянутый в javadocs. Это не относится к Cipher
, поэтому вы не должны считать его потокобезопасным.
Ответ 2
Даже если Cipher был потокобезопасным, было бы бесполезно использовать его из нескольких потоков одновременно.
Байты, которые вы вставляете и выходите из Cipher (через методы update
и finish
), являются непрерывным потоком. Это означает, что с другой стороны они должны быть переданы в том же порядке, чтобы иметь какой-то смысл. Это проще всего сделать, если у вас есть только один поток.
Если вы используете несколько потоков, вы обычно хотите вызвать reset
между вызовами - и тогда вам понадобится внешняя синхронизация.
Ответ 3
Я бы не использовал объекты Cipher из нескольких потоков без синхронизации. Когда вы смотрите на API, есть методы, которые могут работать только при изменении внутреннего состояния, например init()
и update()
. Это делает их неявно небезопасными.