我有一个看起来像这样的课程:
public class Test {
private static final Object someObject = new Object();
public void doSomething()
{
synchronized (someObject) {
System.out.println(someObject.toString());
}
}
}
我可以考虑同步对象,还是有问题,因为它是静态成员?
编辑:请注意,在这种情况下,不同的线程可能正在访问doSomething(),并且必须以线程安全的方式访问对象。
答案 0 :(得分:7)
通过使用静态对象作为监视对象,只有一个使用Test类的任何实例的线程可以进入同步块。如果监视器对象不是静态对象,则持有Test类的不同实例的其他线程可以进入同步块。
答案 1 :(得分:4)
此处 someObject 充当了类型为Test的所有对象的锁定(监视器)。也就是说,如果在两个单独的Test实例上调用doSomething(),则会在另一个实例完成之前阻塞。这与同步方法不同,后者大致相当于上面的代码, someObject 替换为 this 。
将 someObject 更改为非静态将导致按实例锁定。这实际上是“私有锁对象”的习惯用法,如 Effective Java 的第70项所述。
答案 2 :(得分:1)
获取类特定于实例的锁的常见模式是使用Class对象本身:
public class Test {
public void doSomething() {
synchronized (Test.class) {
// something
}
}
}
实际上是同步静态方法的作用。当然,如果您想要多个这样的锁,您需要将它们声明为静态字段,如示例所示。
答案 3 :(得分:0)
如果使用不同的类加载器加载Test类会发生什么?