首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程安全,没有易失性

线程安全,没有易失性
EN

Stack Overflow用户
提问于 2012-02-01 21:13:23
回答 4查看 958关注 0票数 5

有人能解释为什么这个例子没有易失性的线程安全吗?

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

实际上,假设computeHashCode函数总是返回相同的结果,并且没有副作用(即幂等),那么甚至可以消除所有的同步。

代码语言:javascript
复制
// Lazy initialization 32-bit primitives
// Thread-safe if computeHashCode is idempotent
class Foo { 
  private int cachedHashCode = 0;
  public int hashCode() {
    int h = cachedHashCode;
    if (h == 0) {
      h = computeHashCode();
      cachedHashCode = h;
      }
    return h;
    }
  // other functions and members...
  }

更多:我明白了,我们不关心这个值是否计算了两次(所以它并不是真正的线程安全)。我还想知道,在计算了哈希码之后创建的新线程是否保证看到了新的哈希码?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-01 21:21:32

这是在薄冰上行走,但这是一个解释。可见性问题意味着一些线程可能会看到旧版本和一些新版本。在我们的例子中,一些线程看到0,而另一些线程- cachedHashCode

调用hashCode()并查看cachedHashCode的线程只会返回它(不满足if (h == 0)条件),一切都正常。

但是看到0的线程(尽管可能已经计算了cachedHashCode )将重新计算它。

换句话说,在最坏的情况下,每个线程都将第一次进入分支查看0 (比如如果它是ThreadLocal)。

由于computeHashCode()是幂等的(非常重要),所以无论是多次调用它(通过不同的线程)并将它重新分配给相同的变量,都不会产生任何副作用。

票数 8
EN

Stack Overflow用户

发布于 2012-02-01 21:17:43

这里的重要信息是

computeHashCode函数总是返回相同的结果

如果这是真的,那么已知的computeHashCode实际上是不可变的,而且由于它总是相同的值,所以永远不会出现并发问题。

让cachedHashCode变得不稳定。就线程安全性而言,这不会有什么影响,因为您总是分配并返回一个线程局部变量h,它将是一个非零的computedHashCode。

票数 6
EN

Stack Overflow用户

发布于 2012-02-01 21:28:22

这就是所谓的活泼的单一检查成语。当计算一个值是幂等的时候(每次返回相同的值;推论:类型必须是不可变的)和廉价(如果它被意外地重新计算了一次,那就可以了)。这总是以某种形式出现在

代码语言:javascript
复制
class Foo {
  private Value cacheField; // field holding the cached value; not volatile!

  public Value getValue() {
    Value value = cacheField; // very important!
    if (value == 0 or null or whatever) {
      value = computeValue();
      cacheField = value;
    }
    return value;
  }
}

或者差不多等同的东西。如果您的实现不是幂等的,或者不是廉价的,那么您应该使用另一个成语;有关详细信息,请参阅有效的Java项目71。但问题是,线程最多只读取一个cacheField,如果它们看到cacheField处于未计算值的状态,则会重新计算该值。

例如,正如在有效Java中提到的,String.hashCode()就是这样实现的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9103449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档