2008-11-24 24 views
3

我有一个类,它看起来是这样的:静态成员需要特殊的同步块吗?

public class Test { 

private static final Object someObject = new Object(); 

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

} 

我可以考虑要同步的对象,或者是有一个问题,因为它是一个静态成员?

编辑:注意,不同的线程可能正在访问DoSomething的()和对象必须在这种情况下,一个线程安全的方式来访问。

回答

7

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

+0

我不明白。这是否意味着代码片段就像我期待的那样工作? – 2008-11-24 16:21:20

4

这里someObject充当锁(监视器)所有类型Test的对象。也就是说,如果在两个单独的Test实例上调用doSomething(),则会在另一个完成之前阻塞。这与同步方法不同,后者大部分与上述代码相同,someObject取代

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

1

用于获取一个特定的类实例无关的锁像这样的常见模式是使用类对象本身:

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

这是有效地同步的静态方法做什么。当然,如果你想要这样一个以上的锁,你需要将它们声明为静态字段,就像你的例子。

0

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