同步块中的静态与非静态锁定对象 [英] Static versus non-static lock object in synchronized block
问题描述
尝试可视化和理解同步。
- 使用 静态锁定对象(代码A)之间有什么区别和同步块的 非静态锁定对象(代码B)?
- 在实际应用中有何不同?
- 对方不会有什么陷阱?
- 确定使用哪一个的标准是什么?
- 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
public class MyClass1 {
private static final Object lock = new Object();
public MyClass1() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
代码B
public class MyClass2 {
private final Object lock = new Object();
public MyClass2() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
注意
上面的代码显示了构造函数,但您可以在静态方法和非静态方法中讨论行为的不同之处。另外,当synchronized块修改静态成员变量时使用静态锁是否有利?
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.
推荐答案
区别很简单:如果锁定对象位于 static
字段中,那么 MyClass * $的所有实例c $ c>将分享该锁定(即没有两个对象可以同时锁定该对象)。
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.
使用静态锁定对象时:
- 线程1调用
o1.foo()
- 线程2调用
o1.foo()
,必须等待线程1完成 - 主题3 ca lls
o2.foo()
,还必须等待线程1(可能还有2)才能完成
- 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:
- 线程1调用
o1.foo()
- 线程2调用
o1.foo()
,必须等待线程1完成 - 线程3调用
o2.foo()
,它可以继续,而不是注意线程1和2
- 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
您需要哪一项取决于您尝试保护的数据类型使用您的synchronized块。
Which one of those you'll need depends on what kind of data you try to protect with your synchronized block.
根据经验,您希望lock-object具有相同的 static
- 比操作值更高。因此,如果您仅操作非静态值 ,则需要非静态锁定对象。如果你只操作静态值 ,你需要一个静态锁对象。
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.
当你操作静态和非静态值,然后它会变得复杂。 easy 方式只是使用静态锁定对象,但这可能会增加synchronized块的大小,而不是绝对必要,并且可能需要比预期更多的锁争用。在这些情况下,您可能需要静态和非静态锁定对象的组合。
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.
这篇关于同步块中的静态与非静态锁定对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!