Scala SIP-20はレイジーヴァルの新しい実装を提案しています。これはより正確ですが、「現在の」バージョンよりも約25%遅くなります。
提案された実装のルックスが好き:
class LazyCellBase { // in a Java file - we need a public bitmap_0
public static AtomicIntegerFieldUpdater<LazyCellBase> arfu_0 =
AtomicIntegerFieldUpdater.newUpdater(LazyCellBase.class, "bitmap_0");
public volatile int bitmap_0 = 0;
}
final class LazyCell extends LazyCellBase {
import LazyCellBase._
var value_0: Int = _
@tailrec final def value(): Int = (arfu_0.get(this): @switch) match {
case 0 =>
if (arfu_0.compareAndSet(this, 0, 1)) {
val result = 0
value_0 = result
@tailrec def complete(): Unit = (arfu_0.get(this): @switch) match {
case 1 =>
if (!arfu_0.compareAndSet(this, 1, 3)) complete()
case 2 =>
if (arfu_0.compareAndSet(this, 2, 3)) {
synchronized { notifyAll() }
} else complete()
}
complete()
result
} else value()
case 1 =>
arfu_0.compareAndSet(this, 1, 2)
synchronized {
while (arfu_0.get(this) != 3) wait()
}
value_0
case 2 =>
synchronized {
while (arfu_0.get(this) != 3) wait()
}
value_0
case 3 => value_0
}
}
2013年6月現在、このSIPは承認されていません。メーリングリストの議論に基づいて、承認され、Scalaの将来のバージョンに含まれるようになると思います。したがって、Daniel Spiewakの観察に耳を傾けるのは賢明だと思います。
Lazy valは無料ではありません(または安価でもありません)。最適化ではなく、正確さのために遅延が絶対に必要な場合にのみ使用してください。
bitmap$0
です。現在の実装(2.8)では、同期ブロックは1つしかなく、フィールドは揮発性です。