当前位置: 首页 > 面试题库 >

在Java中需要线程安全的MessageDigest

琴英华
2023-03-14
问题内容

我需要在性能关键的环境中使用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返回的对象是否不同,并且它们不会互相干扰?文档说“新”对象,但是我不确定它是否只是(共享)共享具体类的包装?
  3. 如果getInstance()返回“真实”新对象,是否建议每次我需要计算散列时都创建一个新实例?就性能损失而言-它的成本是多少?

我的用例非常简单-只需哈希一个简单的键即可。我无法使用同步。

谢谢,


问题答案:

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

从中返回的所有实例getInstance()都是不同的。它们必须是独立的摘要,因为它们维护着单独的摘要(如果这对您来说还不够用,请在此处找到源链接)。

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



 类似资料:
  • 我找到了关于线程安全的代码,但它没有来自给出示例的人的任何解释。我想知道为什么如果我不在“count”之前设置“synchronized”变量,那么count值将是非原子的(总是=200是期望的结果)。谢谢

  • 考虑一个无状态EJB 从EJB3.1规范中 容器将支持并发执行的会话 bean的许多实例;但是,每个实例只看到一个 序列化的方法调用序列。因此,有状态或 无状态会话bean不必被编码为可重入的 因此无状态seession bean一次最多只能“服务”一个请求,这通常是由管理bean池的容器实现的。这一切的伟大目标是线程安全。 我的问题是为什么我们需要这种形式的线程安全?我的意思是Spring be

  • 问题内容: 经过一番认真的搜索后,我发现RandomAccessFile- class不是线程安全的。现在,我可以使用一个信号量来锁定所有读取和写入,但是我认为这样做的效果不是很好。从理论上讲,一次可以进行多次读取和一次写入。如何用Java做到这一点?有可能吗? 谢谢! 问题答案: 文件的部分锁定是一项复杂的业务,许多操作系统都避免这样做。但是,如果您坚持要这样做,一种方法是设计自己的锁定机制对象

  • 问题内容: 有关Singletons的维基百科文章提到了一些用线程安全的方法来用Java实现结构。对于我的问题,让我们考虑具有冗长的初始化过程并且一次被多个线程访问的Singleton。 首先,这个未提及的方法是线程安全的吗?如果是的话,它在什么上进行同步? 其次,为什么以下实现线程安全且在初始化时是懒惰的?如果两个线程同时进入该方法,到底会发生什么? 最后,在第二个示例中,如果一个线程首先获取一

  • 问题内容: 鉴于以下多态: 我们如何在没有昂贵的getInstance()方法同步和双重检查锁定争议的情况下使它保持线程安全和懒惰?这里提到了单例的有效方法,但似乎并没有扩展到多例。 问题答案: 使用Java 8,它甚至可以更简单:

  • 问题内容: 我知道文档说明该对象是线程安全的,但这是否意味着从所有方法对其进行的所有访问都是线程安全的?因此,如果我一次从多个线程中调用它,并且一次在同一实例上调用它,会不会发生什么不好的事情? 问题答案: 快速答案是肯定的,它们是线程安全的。但是不要让它在那里… 首先,一个小的内部管理是一个接口,任何不是线程安全的实现都将破坏书面合同。您包括的链接是指,它具有一定的灵巧性。 您包含的链接引起了一