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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…