9

可能重复:
避免在 Java 中同步(this)?

两段代码有什么区别?各自的优点和缺点是什么?

1)

public class Example {
    private int value = 0;

    public int getNextValue() {
        synchronized (this) {
            return value++;
        }
    }
}

2)

public class Example {
    private final Object lock = new Object();
    private int value = 0;

    public int getNextValue() {
        synchronized (lock) {
            return value++;
        }
    }
}
4

4 回答 4

8

我选择第二种方法的主要原因是我无法控制客户对我的班级实例所做的事情。

如果出于某种原因,有人决定使用我的类的实例作为锁,他们将干扰我的类中的同步逻辑:

class ClientCode {
    Example exampleInstance;

    void someMethod() {
        synchronized (exampleInstance) {
            //...
        }
    }
}

如果在我的Example课堂上,我使用了一个其他人看不到的锁,它们就不能干扰我的逻辑并像上面的场景一样引入任意互斥锁。

综上所述,这只是信息隐藏原理的一种应用。

于 2012-06-23T09:51:04.280 回答
3

如果我需要同时执行两个彼此独立的不同任务,我更喜欢第二种选择。

例如:

public class Example {
    private int value = 0;
    private int new_value = 0;
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    public int getNextValue() {
        synchronized (lock1) {
            return value++;
        }
    }

    public int getNextNewValue() {
        synchronized (lock2) {              
            return new_value++;
        }
    }
}
于 2012-06-23T09:36:47.327 回答
0

我会说第二种方法更好。考虑以下情况:

public class Abc{

    private int someVariable;

    public class Xyz {
        //some method,synchronize on this
    }

        //some method, and again synchronize on this


}

在这种情况下this,两种方法是不一样的。一种是内部类的方法。因此,最好使用公共对象进行同步。例如,synchronized (someVariable)

于 2012-06-23T07:12:36.363 回答
0

我认为这真的取决于情况。假设您的类是一个子类,而超类有一个具有同步的方法。假设您正在使用相同的数据集,并希望在您的方法中保持完整性。那么绝对方法1是你应该使用的。

否则,根据 Costi 提到的内容,第二种方法会更好

于 2012-06-23T10:10:08.123 回答