When you reference i
in the body of class Main
, what you are really doing is referencing the static variable Main.i
(the compiler is polite and doesn't make you type the full path.) The lambda in this case isn't capturing anything; Main.i
can be evaluated from a static context. So it is if the lambda is desugared to the method
public static void lambda$23() {
System.out.println(Main.i);
}
What should be more clear now is that you've got multiple threads racing to access the shared (mutable!) variable Main.i
; the main thread is updating it, and the created threads are reading it. And because the reads in the new thread are racy, you get no guarantees as to what is printed out.