需要线程安全 MessageDigest in Java

2022-09-01 02:02:57

我需要在性能关键型环境中使用 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(); 

具体说来:

  1. ThreadLocal能保证工作吗?它会有性能损失吗?
  2. getInstance 返回的对象是否不同,并且它们不会相互干扰?文档说“new”对象,但我不确定它是否只是(共享)共享具体类的包装器?
  3. 如果 getInstance() 返回“真实”的新对象,是否建议每次需要计算哈希值时都创建一个新实例?在性能损失方面 - 它的成本有多高?

我的用例非常简单 - 只需散列一个简单的密钥。我无法承受使用同步。

谢谢


答案 1

每次需要时创建一个新实例。MessageDigest

从中返回的所有实例都是不同的。它们需要,因为它们维护单独的摘要(如果这对你来说还不够,这里有一个指向源代码的链接)。getInstance()

ThreadLocal 当与线程池一起使用时,可以提供性能优势,以维护成本高昂的构造对象。 构建起来不是特别昂贵(再次,看看源代码)。MessageDigest


答案 2

作为替代方案,使用 DigestUtils,Apache Commons 的 MessageDigest 线程安全包装器。

sha1() 做你需要的:

byte[] bytes = sha1(key)


推荐