Suppose I have the following inner class, now method1() is accessed by 2 threads, say thread 1 and thread 2, here we are declaring a local variable and incrementing it. Now this local variable is of primitive data type and will exist on stack, since each Thread has it's own memory stack it should not be shared between the threads, but int local is also a part of a static inner class, so I wanted to know whether int local will be shared between the threads or not?
As in if 2 threads simultaneously call the method1() how will the memory distribution be like?
private static class SharedClass {
int a = 0;
public void method1() {
int local = 0;
local++;
a=local;
}
}
Local variables are never shared with other threads in Java. It doesn't matter whether we are talking about ordinary methods, or lambdas. It doesn't matter whether the method is declared in a top level class, an inner class, a nested class, an anonymous class or a local classes.
So in your example, the two threads will have their own copies of the local
variable, but they may be updating a shared a
variable ... depending on which SharedClass
instance they are calling the method on.
Or, to put it another way, you don't need to worry about thread safety for local = 0;
and local++
, but you do for access to a
and the a=local;
assignment.
There some scenario where local variables appear to be shared. However, it is an illusion. Consider this:
public void test() {
final int arg = 42;
new Thread(new Runnable(){
public void run() {
System.out.println(arg);
}
}).start();
}
It looks like the arg
variable is accessed by the child thread. But in fact, what the child thread is actually accessing will be a synthetic variable in the Runnable
instance whose value has been initialized to the value of arg
; i.e. 42
.
(If you compile the above code and use javap
to examine the bytecodes, you will see how it works.)
Note that this is only allowed by the Java compiler when arg
is final
or effectively final. If was not final
or effectively final, the trick of using a synthetic variable would not work.