问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/18356795/static-versus-non-static-lock-object-in-synchronized-block