Reputation: 1489
From the Java memory model, we know that every thread has its own thread stack, and that local variables are placed in each thread's own thread stack.
And that other threads can't access these local variables.
So in which case should we synchronize on local variables?
Upvotes: 40
Views: 28780
Reputation: 31269
There are two situations:
int
or double
.ArrayList
.In the first situation, you can't synchronize, as you can only synchronize on Objects (which are pointed to by reference-type variables).
In the second situation, it all depends on what the local variable points to. If it points to an object that other threads (can) also point to, then you need to make sure that your code is properly synchronized.
Examples: you assigned the local variable from a static
or instance field, or you got the object from a shared collection.
If, however, the object was created in your thread and only assigned to that local variable, and you never give out a reference to it from your thread to another thread, and the objects implementation itself also doesn't give out references, then you don't need to worry about synchronization.
Upvotes: 21
Reputation: 22422
You are talking about the below case:
public class MyClass {
public void myMethod() {
//Assume Customer is a Class
Customer customer = getMyCustomer();
synchronized(customer) {
//only one thread at a time can access customer object
which ever holds the lock
}
}
}
In the above code, customer
is a local reference variable, but you are still using a synchronized block to restrict access to the object customer
is pointing to (by a single thread at a time).
In Java memory model, objects live in heap (even though references are local to a Thread which live in a stack) and synchronization is all about restricting access to an object on the heap by exactly one thread at a time.
In short, when you say local variable (non-primitive), only reference is local, but not the actual object itself i.e., it is actually referring to an object on the heap which can be accessed by many other threads. Because of this, you need synchronization on the object so that single thread can only access that object at a time.
Upvotes: 70
Reputation: 140447
The point is: synchronization is done for a purpose. You use it to ensure that exactly one thread can do some special protection-worthy activity at any given time.
Thus: if you need synchronization, it is always about more than one thread. And of course, then you need to lock on something that all those threads have access to.
Or in other words: there is no point in you locking the door in order to prevent yourself from entering the building.
But, as the other answer points out: it actually depends on the definition of "local" variable. Lets say you have:
void foo() {
final Object lock = new Object();
Thread a = new Thread() { uses lock
Thread b = new Thread() { uses lock
then sure, that "local" variable can be used as lock for those two threads. And beyond that: that example works because synchronization happens on the monitor of a specific object. And objects reside on the heap. All of them.
Upvotes: 6
Reputation: 64632
Yes, it does make sense when the local variable is used to synchronize access to a block of code from threads that are defined and created in the same method as the local variable.
Upvotes: 3