Static versus non-static lock object in synchronized block
The difference is simple: if the locked-on object is in a static
field, then all instances of MyClass*
will share that lock (i.e. no two objects will be able to lock on that object at the same time).
If the field is non-static, then each instance will have its own lock, so only calls of the method on the same object will lock each other.
When you use a static lock object:
- thread 1 calls
o1.foo()
- thread 2 calls
o1.foo()
, will have to wait for thread 1 to finish - thread 3 calls
o2.foo()
, will also have to wait for thread 1 (and probably 2) to finish
When you use a non-static lock object:
- thread 1 calls
o1.foo()
- thread 2 calls
o1.foo()
, will have to wait for thread 1 to finish - thread 3 calls
o2.foo()
, it can just continue, not minding thread 1 and 2
Which one of those you'll need depends on what kind of data you try to protect with your synchronized block.
As a rule of thumb, you want the lock-object to have the same static
-ness than the operated-on value. So if you manipulate non-static values only, you'll want a non-static lock object. If you manipulate static values only, you'll want a static lock object.
When you manipulate static and non-static values, then it'll become complicated. The easy way would be to just use a static lock object, but that might increase the size of the synchronized-block more than absolutely necessary and might need to more lock contention than desired. In those cases you might need a combination of static and non-static lock objects.
In your particular case you use the lock in the constructor, which will only ever be executed once per instance, so a non-static lock-object doesn't make any sense here.
ADTC
As I move around the site, cleaning up after you, tidying up the mess you leave, you don't notice me. But that's okay. I like it clean. I like it smelling fresh. And that's why I'm the janitor. Tools in my arsenal: - Add kbd shortcut - Edit summary options (hacked) - Indentation using Tab key - Keyboard shortcuts for comments Rule of thumb for robust source code: Never assume this line will work as intended when writing the next. Be prepared for surprises. This is me when I'm working: 26MB for $4,995?! IT'S A STEAL!!!
Updated on December 10, 2020Comments
-
ADTC over 3 years
Trying to visualize and understand synchronization.
- What are the differences between using a static lock object (code A) and a non-static lock object (code B) for a synchronized block?
- How does it differ in practical applications?
- What are the pitfalls one would have that the other wouldn't?
- What are the criteria to determine which one to use?
Code A
public class MyClass1 { private static final Object lock = new Object(); public MyClass1() { //unsync synchronized(lock) { //sync } //unsync } }
Code B
public class MyClass2 { private final Object lock = new Object(); public MyClass2() { //unsync synchronized(lock) { //sync } //unsync } }
Note
The above code shows constructors, but you could talk about how the behavior is different in a static method and a non-static method too. Also, would it be advantageous to use a static lock when the synchronized block is modifying a static member variable?
I already looked at answers in this question, but it's not clear enough what the different usage scenarios are.
-
ADTC over 10 yearsI think using the constructor as an example was a bad idea. Anyway, good answer. I want to ask one more question. Is there a way of ensure that a set of methods operating on a volatile static member variable via one thread will be done and over with before other threads access this member variable? I can make this a separate question on SO if necessary.
-
Joachim Sauer over 10 years@ADTC: that does sound like a separate question to me. Short answer: no, you'll need synchronization. You can avoid it only if the operation of the volatile is atomic (for example a single
++
on anint
**and** you don't care about the order (i.e. you don't care if you read before or after the operation). -
ADTC over 10 yearsI do care about the read, it should only happen after the operation. I think I will ask it as a separate question.
-
Joachim Sauer over 10 years@ADTC: actually, I mis-informed you: even
x++
isn't atomic on a volatile x. Do go ahead and ask a new question for this. -
Hussain Akhtar Wahid 'Ghouri' almost 10 yearsif two threads are accessing same object's two diff non-static methods , it is possible or the second thread has to wait , does the lock on one object locks all non-static methods ??
-
Asif Mushtaq over 8 years@HussainAkhtarWahid'Ghouri' Yes, each thread(accessing same object resources) need to wait until other thread leave lock on any same-instance-synchronized-method.