Kotlin by lazy 实现原理
本文的目录如下:
by lazy 到底是什么东西,怎么实现创建一个线程安全的单例?
Kotlin contract是什么
内容开始:

by lazy 到底是什么东西,怎么实现创建一个线程安全的单例?
我们通常可以使用by viewModels就可以创建一个ViewModel供我们使用,不过这次先不谈by viewModels(),我们看看by lazy:
如果直接写by lazy {} 会默认返回一个SynchronizedLazyImpl

SyncrhonizedLazyImpl实现了Lazy接口,同样实现了这个接口的还有后续会谈及的ViewModelLazy。value表示一个不可变属性,在SynchronizedLazyImpl中的实现如下:
本质上还是一个双重校验锁的实现。不过Kotlin中是没有synchronized块的,这里使用了一个函数实现了这个效果:
monitorEnter和monitorExit看不到具体的实现,这里不知道用了什么黑科技,不过应该和JVM的monitorEnter和monitorExit的效果类似。这里需要具体说一下是contract。
Kotlin contract是什么
参考内容:
// Kotlin中的契约:https://droidyue.com/blog/2019/08/25/kotlin-contract-between-developers-and-the-compiler/
Kotlin contract表示Kotlin编译器和开发者之间的一个协定,请看如下的代码:
传入的safeRun lambda编译器不知道它的执行次数,这样有可能会修改val变量AppVersion,无法确定safeRun执行时,getAppVersion是否执行完毕。
所以我们需要加一个constract告诉编译器一些额外的信息:
通过callsInPlace确定runFunction只会在safeRun执行时执行,同时设置EXACTLY_ONCE确定只会执行一次。