静态成员需要特殊的同步块吗?

时间:2008-11-24 16:09:48

标签: java static synchronization locking

我有一个看起来像这样的课程:

public class Test {

private static final Object someObject = new Object();

public void doSomething()
{
    synchronized (someObject) {
        System.out.println(someObject.toString());
    }
}

}

我可以考虑同步对象,还是有问题,因为它是静态成员?

编辑:请注意,在这种情况下,不同的线程可能正在访问doSomething(),并且必须以线程安全的方式访问对象

4 个答案:

答案 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类会发生什么?