3

I wrote the following simple application:

object Main extends App {
    var v: Int = 0
    val t = new Thread(() =>  v = 1)
    t.start()
    t.join()
    println(v) //prints 1
}

The thing that I was confused by was that we modify local variable from another thread... And that modification (made by the other thread) is visible in the main thread.

I thought local variables are always reside in a stack (stack memory the bottom is pointed to rsp register). I thought the stack memory is allocated for each thread in the application.

Upd: Even if we modify the app as follows it prints the same:

object Main {
    def main(args: Array[String]) = {
        var v: Int = 0
        val t = new Thread(() =>  v = 1)
        t.start()
        t.join()
        println(v) //prints 1
    }
}
snovelli
  • 5,804
  • 2
  • 37
  • 50
Some Name
  • 8,555
  • 5
  • 27
  • 77

2 Answers2

8

v is not a local variable in this case. It is a member of Main singletone object.

Update for the second example: Closure () => v = 1 is compiled into an anonymous class that captures all variables it depends on. Stack-allocated primitives are turned into heap-allocated objects. Here it is explained in details: How does the memory management of closures in Scala work?

simpadjo
  • 3,947
  • 1
  • 13
  • 38
2

What this is doing is turning what appears to be a stack object into a heap object. In Java you can do this using array of 1 without adding special classes as Scala does.

public static void main(String... args) {
    int[] v = { 0 };
    Thread t = new Thread(() => v[0] = 1);
    t.start();
    t.join();
    println(v[0]); //prints 1
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130