如何使用循环对象初始化识别/获取自动提示,从而在Scala中导致死锁? [英] How to identify / get automated hints with cyclic object initialization causing deadlocks in Scala?

查看:88
本文介绍了如何使用循环对象初始化识别/获取自动提示,从而在Scala中导致死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于循环对象初始化,以下代码会在将来的超时中运行(在Scala 2.x和Dotty中,-Xcheckinit或-Ycheck-init在这里没有帮助)。在复杂的项目中,这些周期通常被很好地隐藏。是否有可能从编译器或至少在运行时寻求帮助?如何防止这种情况在多线程环境中发生?

The following code runs into future timeouts (in Scala 2.x and Dotty, -Xcheckinit or -Ycheck-init does not help here) because of cyclic object initialization. In complex projects these cycles usually are hidden very well. Is there any possiblity of getting help from the compiler or at least at runtime? How do you prevent this from happening in a multithreaded environment?

import scala.concurrent.Future
import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

object Base {
  val LeftElement = "Left"
  val RightElement = "Right"

  println("Base before: " + Thread.currentThread())
  val all = Set(Left, Right)
  println("Base after: " + Thread.currentThread())
}

object Left {
  println("Left before: " + Thread.currentThread())
  val basePath = Base.LeftElement
}

object Right {
  println("Right before: " + Thread.currentThread())
  val basePath = Base.RightElement
}

object Main extends App {
  val f1 = Future(Left)
  val f2 = Future(Right)
  println(Await.result(f1, 1 second))
  println(Await.result(f2, 1 second))
}


推荐答案

通常,编译器和JVM不能帮助您避免这种情况。

In general, the compiler and JVM will not help you avoid this.

解决此问题的最佳方法是延迟对周期的评估,例如:

The best you can do to address this is delay evaluation of the cycle by, for instance:


  • 使用 lazy val

  • 使用 def

  • using lazy val
  • using def

请注意,相对于简单的 val 会产生一些开销。我还没有做过实验,但是我怀疑 lazy val (会花费一些同步费用)对于像

Note that either results in some overhead relative to a simple val. I haven't done experiments, but I'd suspect that lazy val (incurring the expense of some synchronization) is better for a case like

lazy val all = Set(Left, Right)

以限制分配的冗余对象,对于像这样的情况, def 更好

to limit allocations of redundant objects, and that def is better for a case like

def basePath = Base.LeftElement

因为JIT很可能内联。

since that's pretty likely to be inlined by JIT.

另请参见:如何在静态初始值设定项中诊断或检测死锁

这篇关于如何使用循环对象初始化识别/获取自动提示,从而在Scala中导致死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆