ADT*_*DTC 36 java static synchronization locking synchronized
尝试可视化和理解同步.
代码A.
public class MyClass1 {
private static final Object lock = new Object();
public MyClass1() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
Run Code Online (Sandbox Code Playgroud)
代码B.
public class MyClass2 {
private final Object lock = new Object();
public MyClass2() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
Run Code Online (Sandbox Code Playgroud)
注意
上面的代码显示了构造函数,但您可以在静态方法和非静态方法中讨论行为的不同之处.另外,当synchronized块修改静态成员变量时,使用静态锁是否有利?
我已经在这个问题中查看了答案,但不清楚不同的使用场景是什么.
Joa*_*uer 50
区别很简单:如果锁定的对象在一个static字段中,那么所有的实例MyClass*将共享该锁(即没有两个对象可以同时锁定该对象).
如果该字段是非静态的,则每个实例都有自己的锁,因此只有对同一对象的方法调用才会相互锁定.
使用静态锁定对象时:
o1.foo()o1.foo(),必须等待线程1完成o2.foo(),还必须等待线程1(可能还有2)完成使用非静态锁定对象时:
o1.foo()o1.foo(),必须等待线程1完成o2.foo(),它可以继续,而不是注意线程1和2您需要哪一个取决于您尝试使用synchronized块保护的数据类型.
根据经验,您希望锁定对象具有与static操作值相同的性质.因此,如果仅操作非静态值,则需要非静态锁定对象.如果仅操作静态值,则需要静态锁定对象.
当您操纵静态和非静态值时,它将变得复杂.在简单的方法是只使用一个静态的锁定对象,但可能会增加同步块的大小超过绝对必要的,并比预期可能需要更多的锁争用.在这些情况下,您可能需要静态和非静态锁定对象的组合.
在您的特定情况下,您在构造函数中使用了锁,每个实例只执行一次,因此非静态锁对象在这里没有任何意义.