12

次のコードを検討してください。

public class SynchronizedCounter extends Thread {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public void run() {
        for(;;)
            increment();
    }
}

static void main(String[] args) {
    SynchronizedCounter counter = new SynchronizedCounter();
    counter.start();
    for(;;)
        counter.decrement();
}

これは、increment( )メソッドとdecrement()メソッドが互いに終了するのを待つかどうかを意味しますか?

編集: そしてこれは待ちませんか?

static void main(String[] args) {
    SynchronizedCounter counter1 = new SynchronizedCounter();
    SynchronizedCounter counter2 = new SynchronizedCounter();
    counter1.start();
    for(;;)
        counter2.decrement();
}
4

3 に答える 3

13

はい、synchronizedキーワードは次の略記です。

synchronized(this) {
  //...
}

したがって、両方のメソッドが同じミューテックスオブジェクトを効果的にロックしています。それらを互いに独立させたい場合(この例では、両方が同じ値にアクセスするため、これは悪い考えです)、オブジェクトロックプライベートクラスメンバー-ベストプラクティスを参照してください。(Java)

ところで、他のスレッドのコンストラクターに渡すので、を拡張するのではなくSynchronizedCounter実装する必要があります-今は少し混乱しています。RunnableThread

于 2012-05-13T11:45:00.647 に答える
6

ロックは常にオブジェクト全体にあります。いずれかのsynchronizedメンバーがアクセスされる場合。

最初の例では、同じオブジェクトに対して競合する 2 つのスレッドがあります。1 つは明示的に開始した (無限ループでメソッドを呼び出す) スレッドで、もう 1 つはメイン スレッド (無限に呼び出す) です。counterincrement()decrement()

2 番目の例では、 と の 2 つのオブジェクトが作成されcounter1counter2います。これらは、互いに独立した独自のロックを持ちます。1 つのオブジェクトをロックしても、他のスレッドが他のオブジェクトにアクセスすることには影響しません。2 つのスレッド (明示的なスレッドとメイン スレッド) が 2 つの異なるオブジェクトのロックを取得するため、競合は発生しません

于 2012-05-13T12:03:24.043 に答える
1

これは、increment() メソッドと decrement() メソッドが互いに終了するのを待つということですか?

いいえ、それは、1 つのスレッドがそれらの中にある場合、他のスレッドが increment() および decrement() を呼び出すことができないことを意味します。完了するために、他のスレッドはこのインスタンス/オブジェクトの同期されたメソッドを実行できませんでした

同じインスタンス/オブジェクトをロックせずに、同期されたメソッドから他の同期されたメソッドを呼び出すことができます

于 2012-05-13T18:38:14.630 に答える