9

重複の可能性:
Javaで同期(これ)を回避しますか?

2つのコードの違いは何ですか?それぞれの長所と短所は何ですか?

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

2 番目のアプローチを選択する主な理由は、クライアントがクラスのインスタンスに対して行うことを制御できないためです。

なんらかの理由で、誰かが私のクラスのインスタンスをロックとして使用することを決定した場合、彼らは私のクラス内の同期ロジックを妨害します。

class ClientCode {
    Example exampleInstance;

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

私のExampleクラス内で、他の誰も見ることができないロックを使用している場合、それらは私のロジックに干渉したり、上記のシナリオのように任意のミューテックスを導入したりすることはできません。

要約すると、これは情報隠蔽の原則の適用にすぎません。

于 2012-06-23T09:51:04.280 に答える
3

互いに独立した 2 つの異なるタスクを同時に実行する必要がある場合は、2 番目のオプションをお勧めします。

例えば:

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

本当に状況次第だと思います。クラスがサブクラスであり、スーパークラスに同期のあるメソッドがあるとします。また、同じデータセットを使用していて、メソッド内でも整合性を維持したいとします。次に、間違いなくアプローチ1を使用する必要があります。

そうでなければ、Costiが述べたことに基づいて2番目のアプローチがよりうまく機能するでしょう

于 2012-06-23T10:10:08.123 に答える
0

2番目の方法の方が優れていると思います。次の状況を考慮してください。

public class Abc{

    private int someVariable;

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

        //some method, and again synchronize on this


}

この状況thisでは、2 つの方法で同じではありません。1つは内部クラスのメソッドです。したがって、同期には共通のオブジェクトを使用することをお勧めします。例: synchronized (someVariable).

于 2012-06-23T07:12:36.363 に答える