线程本地变量的性能

从变量中读取的速度比从常规字段读取的速度慢多少?ThreadLocal

更具体地说,简单的对象创建是否比访问变量更快或更慢?ThreadLocal

我认为它足够快,因此拥有实例比每次创建实例要快得多。但是,这是否也适用于字节[10]或字节[1000]?ThreadLocal<MessageDigest>MessageDigest

编辑:问题是打电话时到底发生了什么?如果这只是一个领域,就像其他任何领域一样,那么答案将是“它总是最快的”,对吧?ThreadLocal


答案 1

在2009年,一些JVM使用对象中的非同步实现。这使得它非常快(当然,虽然不如使用常规的现场访问那么快),并确保物体在死亡时得到整理。在2016年更新了这个答案,似乎大多数(所有?)较新的JVM都使用带有线性探测的。我不确定这些性能 - 但我无法想象它比早期的实现要差得多。ThreadLocalHashMapThread.currentThread()ThreadLocalThreadThreadLocalMap

当然,现在也非常快,垃圾回收器也非常擅长回收短命的对象。new Object()

除非您确定对象创建的成本很高,或者您需要逐个线程地保留某些状态,否则最好在需要时使用更简单的分配解决方案,并且仅在探查器告诉您需要时才切换到实现。ThreadLocal


答案 2

运行未发布的基准测试,在我的机器上每次迭代大约需要35个周期。没什么大不了的。在 Sun 的实现中,将 s 映射到值的自定义线性探测哈希映射。因为它只能由单个线程访问,所以它可以非常快。ThreadLocal.getThreadThreadLocal

小对象的分配需要相似的周期数,尽管由于缓存耗尽,您可能会在紧密循环中获得略低的数字。

建筑很可能相对昂贵。它具有相当多的状态,并且构造通过SPI机制进行。例如,您可以通过克隆或提供 .MessageDigestProviderProvider

仅仅因为在 中缓存可能比创建更快,并不一定意味着系统性能会提高。您将有与GC相关的额外开销,这会减慢一切速度。ThreadLocal

除非您的应用程序使用率很高,否则您可能需要考虑改用传统的线程安全缓存。MessageDigest


推荐