I was reading multi-threading in Java and I come across this
Local variables are thread safe in Java.
Since then I have been thinking How/Why local variables are thread safe.
Can somebody please let me know.
On its stack(basically thread stack), local primitives and local reference variables are stored. Hence one thread does not share its local variables with any other thread as these local variables and references are inside the thread's private stack. Hence local variables are always thread-safe.
Local References All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread-safe. In fact, you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads.
Using Final keywordFinal Variables are also thread-safe in java because once assigned some reference of an object It cannot point to reference of another object.
Tip: Unlike class and instance field variables, threads cannot share local variables and parameters. The reason: Local variables and parameters allocate on a thread's method-call stack. As a result, each thread receives its own copy of those variables.
When you create a thread it will have its own call stack created. Two threads will have two stacks and one thread never shares its stack with other thread.
All local variables defined in your program will be allocated memory in stack (As Jatin commented, memory here means, reference-value for objects and value for primitive types) (Each method call by a thread creates a stack frame on its own stack). As soon as method execution is completed by this thread, stack frame will be removed.
There is great lecture by Stanford professor in youtube which may help you in understanding this concept.
Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.
public void someMethod(){
long threadSafeInt = 0;
threadSafeInt++;
}
Local references to objects are a bit different. The reference itself is not shared. The object referenced however, is not stored in each threads's local stack. All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread safe. In fact you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads
Think of methods like definitions of functionality. When two threads run the same method, they are in no way way related. They will each create their own version of each local variable, and will be unable to interact with each other in any way.
If variables aren't local (like instance variables defined outside of a method at the class level), then they are attached to the instance (not to a single run of the method). In this case, two threads running the same method both see the one variable, and this isn't thread-safe.
Consider these two cases:
public class NotThreadsafe {
int x = 0;
public int incrementX() {
x++;
return x;
}
}
public class Threadsafe {
public int getTwoTimesTwo() {
int x = 1;
x++;
return x*x;
}
}
In the first, two threads running on the same instance of NotThreadsafe
will see the same x. This could be dangerous, because the threads are trying to change x! In the second, two threads running on the same instance of Threadsafe
will see totally different variables, and can't affect each other.
Each method invocation has its own local variables and, obviously, a method invocation happens in a single thread. A variable that is only updated by a single thread is inherently thread-safe.
However, keep a close eye on what exactly is meant by this: only the writes to the variable itself are thread-safe; calling methods on the object that it refers to is not inherently thread-safe. Same goes for directly updating object's variables.
Thread will have its own stack. Two threads will have two stacks and one thread never shares its stack with other thread. Local variables are stored in each thread's own stack. That means that local variables are never shared between threads.
In addition to the other answers such as Nambari's.
I'd like to point out that you can use a local variable in an anoymous type method:
This method could be called in other threads which could compromise threadsafety, so java forces all local variables used in anoymous types to be declared as final.
Consider this illegal code:
public void nonCompilableMethod() {
int i=0;
for(int t=0; t<100; t++)
{
new Thread(new Runnable() {
public void run() {
i++; //compile error, i must be final:
//Cannot refer to a non-final variable i inside an
//inner class defined in a different method
}
}).start();
}
}
If java did allow this (like C# does through "closures"), a local variable would no longer be threadsafe in all circumstances. In this case, the value of i
at the end of all the threads is not guaranteed to be 100
.
Basically Four Type Of Storage Are There in java to store Class Information and data:
Method Area,Heap,JAVA Stack,PC
so Method area and Heap is shared by all the threads but every thread is having its own JAVA Stack and PC and that is not shared by any other Threads.
Each method in java is as Stack frame. so, when one method is called by a thread that stack frame is loaded on its JAVA Stack.All the local variable which are there in that stack frame and related operand stack are not shared by others. PC will have information of next instruction to execute in method's byte code. so all the local variables are THREAD SAFE.
@Weston has also Given good answer.
Java thread safe of local variables
Only local variables are stored on the thread stack.
Local variable that is primitive type
(e.g. int, long...) is stored on the thread stack
and as a result - other thread does not have an access to it.
Local variable that is reference type
(successor of Object
) contains from 2 parts - address(which is stored on thread stack
) and the object(which is stored on heap
)
class MyRunnable implements Runnable() {
public void run() {
method1();
}
void method1() {
int intPrimitive = 1;
method2();
}
void method2() {
MyObject1 myObject1 = new MyObject1();
}
}
class MyObject1 {
MyObject2 myObject2 = new MyObject2();
}
class MyObject2 {
MyObject3 myObject3 = MyObject3.shared;
}
class MyObject3 {
static MyObject3 shared = new MyObject3();
boolean b = false;
}
[JVM Memory model]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With