您可以在特定的对象上进行同步,该对象可以是某些指定的静态锁对象,也可以是类对象(在声明静态方法被同步时发生):
class X { private static final Object lock = new Object(); public void oneAtATime() { synchronized (lock) { // Do stuff } }}class Y { public void oneAtATime() { synchronized (Y.class) { // Do stuff } }}每个变体都有其优点和缺点;对类的锁定允许类外的其他代码出于自身原因使用相同的锁定(这使它可以比您提供的内容编排更多的高级同步),而该
staticfinal Objectlock方法允许您通过设置锁定字段来禁止使用它私有(这样可以更轻松地推断出锁定状态,避免由于其他人编写的错误代码而导致代码死锁)。
当然,您也可以使用from的一些同步机制
java.util.concurrent,例如explicit
Locks,它提供了对锁定的更多控制(
ReentrantLock当前在高竞争下比隐式锁定要好一些)。
编辑: 请注意,静态/全局锁并不是一个好方法-
这意味着曾经创建的类的每个实例实际上都会与其他每个实例绑定在一起(除了使测试或阅读代码变得更加困难之外,还可以严重损害可扩展性)。我假设您这样做是为了同步某种全局状态?在那种情况下,我会考虑将全局/静态状态包装在一个类中,并按实例而不是全局实现同步。
代替这样的事情:
class Z { private static int state; public void oneAtATime(){ synchronized (Z.class) { state++; } }}像这样做:
class State { private int value; public synchronized void mutate(){ value++; }}class Z { private final State state; public Z(State state){ this.state = state; } public void oneAtATime(){ state.mutate(); }}// Usage:State s1 = new State(), s2 = new State();Z foo = new Z(s1);Z bar = new Z(s1);Z frob = new Z(s2);Z quux = new Z(s2);现在
foo和
bar仍然相互联系,但是它们可以独立于
frob和进行工作
quux。



