【问题标题】:How to start lazy init on worker thread如何在工作线程上启动惰性初始化
【发布时间】:2019-03-09 23:22:32
【问题描述】:

我有一个字段val mThing,我用by lazyThing() 初始化。现在我希望lazyThing() 调用需要一点时间,所以我想在工作线程上开始初始化。显然,如果有其他线程出现并需要mThing 并等待它,那很好,但我想尽快在工作线程上开始初始化。在 Kotlin 中这样做有什么好看的方法?

或者如果有比延迟初始化更好的模式,我愿意接受建议。

【问题讨论】:

  • 为什么需要工作线程?如果您不在乎初始化时线程是否阻塞,那么我想只要初始化是同步的,您就可以简单地运行lazyThing() 并让线程阻塞。我不知道用例,但这在例如 Android 应用程序中通常是非常危险的,您可能会不小心阻塞无法阻塞的 UI 线程。在其他情况下,这可能完全没问题。
  • @Fred 工作线程正是出于这个原因而需要的。从理论上讲,如果某些 UI 依赖项需要此对象,那么我们当然必须等待(我们不会阻塞 UI 线程,但同时我们可能需要显示一个微调器),所以启动起来会很好工作线程上的初始化。我们可以通过多种方式实现这一点,但我希望看到一些干净的方式
  • 那么我会说使用 kotlin 委托进行延迟初始化似乎不合适。这些将阻塞线程,直到结果可用。语义也需要这样的行为,因为一旦你读取一个变量,你期望结果会被同步读取。它延迟初始化的事实我想这是一个内部细节。在准备好使用之前读取变量而不阻塞是很奇怪的。你会返回什么中间值?在这种情况下,我会暴露一个工作人员或调用者知道会异步运行的东西——就像 rxjava observables 通常做的那样。

标签: kotlin


【解决方案1】:

您可以在lazy 函数中指定同步模式: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-lazy-thread-safety-mode/index.html

云最简单的方法是让 JVM 在类加载时进行初始化。因此,您可以声明一个具有计算结果字段的类或对象。接下来,JVM 会做必要的锁:

object ComputeValueOnClassLoad {
  val value = lazyThing()
}

第一个工作线程将使用该类,它将初始化类加载并因此计算值。其他线程会等待它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2017-07-30
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多