【问题标题】:Are transient objects safe from double-checked locking?瞬态对象是否可以避免双重检查锁定?
【发布时间】:2014-09-05 19:44:12
【问题描述】:

瞬态对象是否可以避免双重检查锁定?

private transient java.lang.ThreadLocal __hashHistory;
public int hashCode() {
    if (__hashHistory == null) {
        synchronized (this) {
            if (__hashHistory == null) {
                __hashHistory = new java.lang.ThreadLocal();
            }
        }
    }

或者对象需要是易失的?

【问题讨论】:

  • 我看不出瞬态变量与双重检查锁定有何关系。如果应用了双重检查锁定,我相信 volatile 只是一种开销,因为您将实现一个同步块。所以 answer 是一个没有任何修饰符的私有变量就足够了。
  • 我认为它可能相关的原因是因为我们之前的防御工事报告没有双重检查锁定问题,而且我知道这段代码在防御工事期间已经到位。因此,加强代码的前一个人找到了不去修复双重检查锁定问题的理由,或者他们当时没有意识到这是一个问题/当那个强化时它没有被认为是一个问题发生(大约 6 年前)。
  • 也许transient关键字被放在那里是为了序列化,这不会以任何方式影响双重检查锁定过程。
  • @RamiStefanidis 没有volatilesynchronized 块是不够的。阅读:jeremymanson.blogspot.com/2008/05/double-checked-locking.html

标签: java object transient


【解决方案1】:

transient 表示在序列化过程中应该忽略该字段。这个关键字与线程锁定无关,所以一切都保持安全或不安全,就像没有它一样。我也不确定volatile 是否会有所帮助。

在您的代码中,如果__hashHistory == null,则两个线程可能同时接近synchronized 语句。他们将一个一个地传递同步语句的主体,但仍然会创建两个ThreadLocal。这就是为什么双重检查锁定被认为是反模式的原因:很难做到正确。

【讨论】:

  • 它可以在“新”内存模型下与volatile 一起使用。代码的唯一问题是在公开可见的对象上同步。
【解决方案2】:

Transient 与线程安全无关。瞬态关键字与序列化有关。 http://en.wikibooks.org/wiki/Java_Programming/Keywords/transient

Volatile 仅确保您读取的是字段的全局值,而不是本地线程缓存的值。它不保证该字段在一条指令到下一条指令之间是否保持不变。所以你必须仔细检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多