【发布时间】:2013-08-21 11:58:42
【问题描述】:
试图形象化和理解同步。
- 使用静态锁对象(代码A)和非静态锁对象有什么区别 同步块的strong>(代码B)?
- 在实际应用中有何不同?
- 一个人会遇到哪些人不会遇到的陷阱?
- 确定使用哪一个的标准是什么?
代码 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
}
}
注意
上面的代码显示了构造函数,但你也可以讨论一下静态方法和非静态方法的行为有何不同。另外,当同步块修改静态成员变量时,使用静态锁会有好处吗?
我已经看过this question中的答案,但还不够清楚不同的使用场景是什么。
【问题讨论】:
-
"请注意,上面的代码显示了构造函数,"这是一个重要的区别。在构造函数上带有实例字段的同步块绝对没有意义,因为没有两个线程会在同一个实例上执行构造函数。
-
实际上,想想看,实例字段可以包含一个线程间共享的对象。例如
private final Object lock = "niceLiteralString";. -
我知道使用构造函数来展示一个例子是个坏主意。我的问题也延伸到静态和非静态方法。另外,共享静态/实例字段如何影响锁定?
-
"共享静态/实例字段如何影响锁定?"锁不在字段上,而是在字段包含的 object instance 上。所以
synchronized (a){}; synchronized(b){}; synchronized(c){}最终可能都使用同一个锁。如果该字段为空,它们也可以抛出 NullPointerExceptions。 -
@Thilo this article 提出应该避免使用字符串文字是有充分理由的——JVM 重用引用。
标签: java static synchronization locking synchronized