Нужна потоковая безопасность MessageDigest в Java

Мне нужно хэшировать несколько ключей из нескольких потоков, используя MessageDigest в критичной для производительности среде. Я узнал, что MessageDigest не является потокобезопасным, поскольку он сохраняет свое состояние в объекте. Каким может быть наилучший способ достижения потокового безопасного хеширования ключей?

Случай использования:

MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");

//somewhere later, just need to hash a key, nothing else
messageDigest.update(key);
byte[] bytes = messageDigest.digest(); 

В частности:

  • Будет ли ThreadLocal гарантированно работать? Будет ли производительность штраф?
  • Являются ли объекты, возвращаемые getInstance разными, и они не мешают друг другу? В документации указано "новое" объект, но я не уверен, является ли это просто оболочкой (совместно используемой) общий конкретный класс?
  • Если getInstance() возвращает "реальные" новые объекты, целесообразно создавать новый экземпляр каждый раз, когда мне нужно рассчитать хэш? Что касается штрафа за производительность - насколько дорого это?

Мой пример использования очень прост - просто хэш - простой ключ. Я не могу позволить использовать синхронизацию.

Спасибо,

Ответы

Ответ 1

Создайте новый экземпляр MessageDigest каждый раз, когда вам это нужно.

Все экземпляры, возвращаемые из getInstance(), различны. Они должны быть, поскольку они поддерживают отдельные дайджесты (и если этого недостаточно для вас, здесь ссылка на источник).

ThreadLocal может обеспечить преимущество в производительности при использовании с threadpool, чтобы поддерживать дорогостоящие объекты. MessageDigest не особенно дорого стоит (еще раз посмотрите на источник).

Ответ 2

В качестве альтернативы используйте DigestUtils, потокобезопасную оболочку Apache Commons для MessageDigest.

sha1() делает то, что вам нужно:

byte[] bytes = sha1(key)

Ответ 3

DigestUtils, похоже, уже не является потокобезопасным, чем raw MessageDigest. Все еще использует MessageDigest.getInstance под обложками.