为了账号安全,请及时绑定邮箱和手机立即绑定

Scala 在线程中处理“共享”局部变量的方式与 Java 不同?它是如何工作的?

Scala 在线程中处理“共享”局部变量的方式与 Java 不同?它是如何工作的?

浮云间 2021-06-22 17:18:33
我对局部变量如何工作的心理模型是它们存储在堆栈中,每个线程都有自己的堆栈,并且线程之间不能访问堆栈。在 Java 中,我实际上不确定如何修改衍生线程中的局部变量,因为编译器抱怨我无法在 lambda 或内部类中修改它。但是,在 Scala 中我可以这样做:implicit val ec = scala.concurrent.ExecutionContext.globalvar i = 5val f = Future {  println((1, i))  i = 6  println((1, i))}val g = Future {  println((2, i))  println((2, i))  println((2, i))}Await.result(f, 3.seconds)并获得结果(2,5)(1,5)(2,5)(2,6)(1,6)线程#2 如何看到线程#1 的修改?
查看完整描述

1 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

你说得对。每个线程都有自己的堆栈,局部变量驻留在堆栈上。


这就是 Java 局部变量应该是 final 或有效 final 的原因。但是你可以使用一个众所周知的单元素数组技巧,这样指向数组的指针实际上是最终的并驻留在堆栈中,但数组的元素可以在闭包内更改。像这样:


int a[] = new a[0];

Thread t = new Thread(() -> {

    a[0] = 1;

});

//...

在 Scala 中,编译器为您制作了类似的东西,并将它们放在堆上,而不是自己放在堆栈上。(抱歉,无法编写一个简单的 Scala 示例并立即查看其字节码,但使用 非常简单易读javap -c)


查看完整回答
反对 回复 2021-06-30
  • 1 回答
  • 0 关注
  • 188 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信