multithreading - 如何识别/获取循环对象初始化导致Scala死锁的自动提示?
问题描述
由于循环对象初始化,以下代码会遇到未来的超时(在 Scala 2.x 和 Dotty 中,-Xcheckinit 或 -Ycheck-init 在这里没有帮助)。在复杂的项目中,这些周期通常隐藏得很好。是否有可能从编译器或至少在运行时获得帮助?在多线程环境中如何防止这种情况发生?
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 不会帮助您避免这种情况。
解决此问题的最佳方法是延迟评估周期,例如:
- 使用
lazy val
- 使用
def
请注意,与简单的val
. 我没有做过实验,但我怀疑lazy val
(产生一些同步的费用)对于像这样的情况更好
lazy val all = Set(Left, Right)
限制冗余对象的分配,这def
对于像这样的情况更好
def basePath = Base.LeftElement
因为这很可能会被 JIT 内联。
另请参阅:如何诊断或检测静态初始化程序中的死锁
推荐阅读
- azure-devops - 在 Azure DevOps 中使用 dotnet CLI 发布预发布 NuGet 包
- android - 如何从 TextView (Kotlin, Android) 获取触摸事件
- mongodb - TypeError:MongoStore.create 不是函数
- javascript - 为什么onclick()函数不点击就自动运行
- asp.net-core - 调试 Blazor 电路错误
- scala - 在 scala 中对嵌套 Map 进行平面映射
- r - 通过过滤掉特定数据,使用现有数据创建新数据框
- reactjs - 拖动文件并选择要反应的文件
- processing - 处理方形堆叠循环
- sql - 查询具有多个状态条件的id