需要知道在 Scala 未来迭代中分配变量是否正确
Need to know if assigning variable in Scala future iteration is correct
给定以下 Scala 代码:
object TestFutures6 extends App {
val f0 = Future { 0 }
val f1 = Future { 1 }
val f2 = Future { 2 }
val fx = Seq(f0,f1,f2)
var x: String = _
println("x="+x)
fx.map {
seq => seq.map { i =>
println("i="+i)
if (x == null) {
x = "abc"
println("x="+x)
}
}
}
Thread.sleep(5000)
}
我需要知道将 "abc" 分配给变量 x
是否符合 运行 条件,因为 seq.map
中的迭代可能 运行平行线。当我 运行 代码时,我只打印了一次 "abc",但我想知道是否有问题。
此外,我需要 运行 在以下上下文中播放此代码
import play.api.libs.concurrent.Execution.Implicits.defaultContext
从技术上讲这里存在潜在的竞争条件,尽管它可能永远不会真正发生。
从本质上讲,您依赖的事实是这两行永远不会 "interleaved" 在不同的线程中:
if (x == null) {
x = "abc"
如果两个线程在执行将 x 设置为 abc 之前执行空检查,那么它们都将进入该块。
在这个玩具示例中可能不会发生这种情况,因为您的 future 非常简单并且会立即完成,但这是非常糟糕的做法,不应出现在任何生产代码中。
这当然不是线程安全的,并且通常行为是不确定的。当您 运行 它时,您可能看不到问题,但我们不知道您使用的是什么执行上下文。
一般情况下,线程和有状态不会一起出现。如果您必须具有可变状态,请使用为状态设计的 library/technique(例如演员)。
给定以下 Scala 代码:
object TestFutures6 extends App {
val f0 = Future { 0 }
val f1 = Future { 1 }
val f2 = Future { 2 }
val fx = Seq(f0,f1,f2)
var x: String = _
println("x="+x)
fx.map {
seq => seq.map { i =>
println("i="+i)
if (x == null) {
x = "abc"
println("x="+x)
}
}
}
Thread.sleep(5000)
}
我需要知道将 "abc" 分配给变量 x
是否符合 运行 条件,因为 seq.map
中的迭代可能 运行平行线。当我 运行 代码时,我只打印了一次 "abc",但我想知道是否有问题。
此外,我需要 运行 在以下上下文中播放此代码
import play.api.libs.concurrent.Execution.Implicits.defaultContext
从技术上讲这里存在潜在的竞争条件,尽管它可能永远不会真正发生。
从本质上讲,您依赖的事实是这两行永远不会 "interleaved" 在不同的线程中:
if (x == null) {
x = "abc"
如果两个线程在执行将 x 设置为 abc 之前执行空检查,那么它们都将进入该块。
在这个玩具示例中可能不会发生这种情况,因为您的 future 非常简单并且会立即完成,但这是非常糟糕的做法,不应出现在任何生产代码中。
这当然不是线程安全的,并且通常行为是不确定的。当您 运行 它时,您可能看不到问题,但我们不知道您使用的是什么执行上下文。
一般情况下,线程和有状态不会一起出现。如果您必须具有可变状态,请使用为状态设计的 library/technique(例如演员)。