4

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

public class Test {

private static final Object someObject = new Object();

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

}

我可以认为对象是同步的,还是因为它是静态成员而存在问题?

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

4

4 回答 4

7

通过使用静态对象作为监控对象,只有一个使用 Test 类的任何实例的线程可以进入同步块。如果监视器对象不是静态对象,则持有不同 Test 类实例的其他线程可能会进入同步块。

于 2008-11-24T16:16:07.913 回答
4

这里someObject充当所有Test 类型对象的锁(监视器)。也就是说,如果在两个单独的 Test 实例上调用 doSomething(),则一个将在另一个完成之前阻塞。这与同步方法不同,同步方法基本上等同于上面的代码,其中someObject被替换为this

将someObject更改为非静态将导致每个实例锁定。这本质上是有效 Java的第 70 项中描述的“私有锁定对象”习语。

于 2008-11-24T16:27:45.427 回答
1

像这样获取特定于类的独立于实例的锁的常见模式是使用 Class 对象本身:

public class Test {
  public void doSomething() {
    synchronized (Test.class) {
      // something
    }
  }
}

这实际上是同步静态方法所做的。当然,如果您想要多个这样的锁,则需要像示例中那样将它们声明为静态字段。

于 2008-11-24T21:12:20.220 回答
0

如果使用不同的类加载器加载测试类会发生什么?

于 2010-12-14T16:15:02.177 回答