我有一个关于JMM和Scala期货的问题。
在下面的代码中,我有一个不可变的数据类。我在一个线程(在未来应用程序中)中创建它的一个实例,然后订阅完成事件。
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Hello extends App {
Future {
new Data(1, "2")
}.foreach { d =>
println(d)
}
Thread.sleep(100000)
}
class Data(var someInt: Int, var someString: String)我们能否保证:
发布于 2019-07-06 00:40:01
完成happens-before回调执行。
免责声明:我是主要的贡献者。
发布于 2019-07-03 04:04:59
我有个类似的问题,我发现-
1)在Intellij医生的报告中,他很方便地为我停了下来。
当值变为可用时,异步处理将来的值.
2)在https://docs.scala-lang.org/overviews/core/futures.html上,它说
一旦未来完成,结果就会变得可用。
基本上,它没有任何地方,我可以找到明确地说,有一个记忆障碍。然而,我怀疑这是一个安全的假设。否则,语言就根本不起作用。
发布于 2019-07-03 09:06:23
您可以通过查看Promise/DefaultPromise/Future,的源代码来了解这一点,该源代码计划执行上下文中的foreach回调/将其添加到侦听器,而不需要在原始线程上运行任何特殊的逻辑.
但是,您也可以通过尝试设置一个执行上下文和线程来验证它,以便在创建Future的Data完成时,其他东西已经排队等待执行。
implicit val context = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2))
Future {
new Data(1, "2")
println("Data created on: " + Thread.currentThread().getName)
Thread.sleep(100)
}.foreach { _ =>
println("Data completed on: " + Thread.currentThread().getName)
}
Future { // occupies second thread
Thread.sleep(1000)
}
Future { // queue for execution while first future is still executing
Thread.sleep(2000)
}我的产出:
创建的数据:池-$n-线程-1 数据已完成:池-$n-线程-2
2.
在这里没有我想要的那么自信,但我要尝试一下:
是的,
DefaultPromise是底层的Future结构,它正在包装一个原子引用,它的行为就像一个易失性变量。由于用于更新结果的写操作必须在读取之前进行,因此必须将结果传递给侦听器,以便它能够运行回调,因此JMM易失性变量规则将其转换为happens-before关系。
https://stackoverflow.com/questions/52870675
复制相似问题