Scala lazy 实现原理

Lazy 有啥用

延迟计算:被 lazy 修饰的变量只有在第一次调用的时候,才会被初始化

1
2
lazy val queue: LinkedBlockingQueue[RequestSetting] = new LinkedBlockingQueue[RequestSetting]()
def pushWhenNoDuplicate(request: RequestSetting): Unit = this.queue.add(request)

当第一次调用 pushWhenNoDuplicate 的时候,queue 才会被初始化

如何实现

scala 最终是要被编译成 class 字节码,才能运行在 jvm 上的

所以我们通过 jd-gui 来看看 lazy 在 class 文件中长什么样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private LinkedBlockingQueue<RequestSetting> queue;
private volatile boolean bitmap$0;

public TargetRequestTaskQueue(DuplicateRemovedStrategy duplicateRemovedStrategy)
{
super(duplicateRemovedStrategy);
}

private LinkedBlockingQueue<RequestSetting> queue$lzycompute()
{
synchronized (this)
{
if (!this.bitmap$0)
{
this.queue = new LinkedBlockingQueue();this.bitmap$0 = true;
}
}
return this.queue;
}

private LinkedBlockingQueue<RequestSetting> queue()
{
return !this.bitmap$0 ? queue$lzycompute() : this.queue;
}

通过代码看出,lazy 是通过 volatile + synchronized 的组合来实现延迟加载的