Scala treats "sharing" local variables in threading differently from Java? How does it work?

allidoiswin :

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.

However, in Scala I can do this:

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?

St.Antario :

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. 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. (Sorry, cannot write a simple Scala example and look at its bytecode rightaway, but it is pretty straightforward and readable with javap -c)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=103778&siteId=1