斯卡拉懒惰值:性能惩罚?线程?

时间:2010-11-04 09:11:10

标签: performance scala lazy-initialization

  

可能重复:
  What's the (hidden) cost of lazy val? (Scala)

Scala允许定义延迟值

lazy val maybeUnusedValue = someCostlyInitialization

其中someCostlyInitialization仅在首次使用maybeUnusedValue时进行评估。也就是说,它最多被评估一次,如果从未使用maybeUnusedValue,它也永远不会被评估。

这线程安全吗?这有什么性能影响? 如果这是线程安全的,它必须以某种方式使用某种同步/使用Java volatile。不幸的是,Scala language specification对此一无所知。

2 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:7)

更新:OOPS,正如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变量的双重检查范例。所以我认为这是安全的