15

可能重复:
lazy val 的(隐藏)成本是多少?(斯卡拉)

Scala 允许定义惰性值

lazy val maybeUnusedValue = someCostlyInitialization

wheresomeCostlyInitialization仅在第一次使用时评估maybeUnusedValue. 也就是说,它最多被评估一次,如果maybeUnusedValue从不使用,它也永远不会被评估。

这是线程安全的吗?这对性能有何影响?如果这是线程安全的,它必须使用某种同步/以某种方式使用 Java volatile。不幸的是,Scala 语言规范对此只字未提。

4

2 回答 2

13

使用双重检查锁定使其成为线程安全http://code-o-matic.blogspot.com/2009/05/double-checked-locking-idiom-sweet-in.html显然这确实意味着访问惰性 val比非懒惰的慢。

于 2010-11-04T09:20:45.050 回答
7

更新:糟糕,正如 Vasil 指出的那样,问题是另一个线程的副本,而且碰巧,这个答案也是如此。

我上了这门课:

class Foo {
  lazy val test = "hi"
}

编译和反编译(使用 jd-gui):

public class Foo
  implements ScalaObject
{
  private String test;
  public volatile int bitmap$0;

  public String test()
  {
    if (
      (this.bitmap$0 & 0x1) == 0);
    synchronized (this)
    {
      if (
        (this.bitmap$0 & 0x1) == 0) {
        this.test = "hi"; this.bitmap$0 |= 1; } return this.test;
    }
  }
}

如您所见,它使用带有 volatile 变量的双重检查范例。所以我认为这是安全的

于 2010-11-04T09:20:05.927 回答