Java 同步块中的静态与非静态锁定对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18356795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static versus non-static lock object in synchronized block
提问by ADTC
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?
- 对同步块使用静态锁对象(代码 A)和非静态锁对象(代码 B)有什么区别?
- 它在实际应用中有何不同?
- 一个人会遇到哪些其他人不会的陷阱?
- 决定使用哪一个的标准是什么?
Code A
代码 A
public class MyClass1 {
private static final Object lock = new Object();
public MyClass1() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
Code B
代码 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.
我已经看过这个问题的答案,但还不够清楚不同的使用场景是什么。
采纳答案by Joachim Sauer
The difference is simple: if the locked-on object is in a static
field, then all instances of MyClass*
will sharethat lock (i.e. no two objects will be able to lock on that object at the same time).
区别很简单:如果锁定的对象在一个static
字段中,那么 的所有实例都MyClass*
将共享该锁(即,没有两个对象能够同时锁定该对象)。
If the field is non-static, then each instance will have its own lock, so only calls of the method on the same objectwill 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 alsohave to wait for thread 1 (and probably 2) to finish
- 线程 1 调用
o1.foo()
- 线程 2 调用
o1.foo()
,必须等待线程 1 完成 - 线程 3 调用
o2.foo()
,还必须等待线程 1(可能还有 2)完成
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
- 线程 1 调用
o1.foo()
- 线程 2 调用
o1.foo()
,必须等待线程 1 完成 - 线程 3 调用
o2.foo()
,它可以继续,不介意线程 1 和 2
Which one of those you'll need depends on what kind of data you try to protectwith 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.
根据经验,您希望锁定对象static
与操作值具有相同的-ness。所以,如果你处理非静态值只,你会想要一个非静态锁定对象。如果您只操作静态值,您将需要一个静态锁对象。
When you manipulate static and non-staticvalues, then it'll become complicated. The easyway 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.
在您的特定情况下,您在构造函数中使用锁,每个实例只会执行一次,因此非静态锁对象在这里没有任何意义。