Scala允许定义延迟值
lazy val maybeUnusedValue = someCostlyInitialization
其中someCostlyInitialization
仅在首次使用maybeUnusedValue
时进行评估。也就是说,它最多被评估一次,如果从未使用maybeUnusedValue
,它也永远不会被评估。
这线程安全吗?这有什么性能影响? 如果这是线程安全的,它必须以某种方式使用某种同步/使用Java volatile。不幸的是,Scala language specification对此一无所知。
答案 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变量的双重检查范例。所以我认为这是安全的