简体   繁体   English

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

[英]Scala treats “sharing” local variables in threading differently from Java? How does it work?

My mental model of how local variables work is they are stored on the stack, and each thread has their own stack and stacks cannot be accessed between Threads. 我对局部变量如何工作的心理模型是存储在堆栈中,每个线程都有自己的堆栈,并且不能在线程之间访问堆栈。

In Java, I'm actually not sure how I would modify a local variable in a spawned thread since the compiler complains I can't modify it in a lambda or in an inner class. 在Java中,我实际上不确定如何在生成的线程中修改局部变量,因为编译器抱怨我无法在lambda或内部类中修改它。

However, in Scala I can do this: 但是,在Scala中我可以这样做:

implicit val ec = scala.concurrent.ExecutionContext.global

var i = 5

val 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)

and obtain a result of 并获得结果

(2,5)
(1,5)
(2,5)
(2,6)
(1,6)

How does thread #2 see the modification from thread #1? 线程#2如何看到线程#1的修改?

You are exactly right. 你是完全正确的。 Each thread has its own stack and local variables reside on the stack. 每个线程都有自己的堆栈,局部变量驻留在堆栈上。

This is the reason in Java local variables should be final or effectively final. 这就是Java局部变量应该是最终或有效最终的原因。 But you can employ a well-known single element array trick so the pointer to an array is effectively final and resided on the stack, but the element of the array can be changed from within a closure. 但是你可以使用一个众所周知的单元素数组技巧,因此指向数组的指针实际上是最终的并且驻留在堆栈上,但是数组的元素可以从闭包内更改。 Like this: 像这样:

int a[] = new a[0];
Thread t = new Thread(() -> {
    a[0] = 1;
});
//...

In Scala compiler makes similar things for you and place them on the heap instead of the stack by itself. 在Scala编译器中为您做类似的事情并将它们放在堆而不是堆栈本身。 (Sorry, cannot write a simple Scala example and look at its bytecode rightaway, but it is pretty straightforward and readable with javap -c ) (对不起,不能写一个简单的Scala示例并立即查看它的字节码,但javap -c非常简单易读)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM