3

次のコードがあるとします。

class MyClass {
    synchronized void myMethod1() {
        //code 
    }

    synchronized void myMethod2() {
        //code
    }
}

ここで、個別のデータmyMethod1()にアクセスするとします。myMethod2()ここで、スレッド A 呼び出しのみmyMethod1()とスレッド B 呼び出しのみの 2 つのスレッドがある場合myMethod2()

スレッド A が実行中の場合、同じデータにアクセスしなくても、myMethod1()スレッド B は待機をブロックし、その理由はありませんか? myMethod2()私の知る限り、同期されたメソッドは、thisインスタンスメソッドにはオブジェクトのモニターを使用し、MyClass.class静的関数にはオブジェクトのモニターを使用します。

4

5 に答える 5

1

メソッドはsychronizedオブジェクト自体をロックします。したがって、各メソッドは、他のメソッドがアクセスを終了してオブジェクトを解放するまで待機する必要があります。メソッドが本当に個別のデータにアクセスしている場合は、次のようなことができます。

class MyClass {
    private static Object mLock1 = new Object();
    private static Object mLock2 = new Object();

    void myMethod1() {
        synchronized(mLock1) {
            //code 
        }
    }

    void myMethod2() {
        synchronized(mLock2) {
            //code 
        }
    }
}

そして、それらに個別にアクセスできます。

編集: 基本的に、同期されたメソッドはこれと同等であると考えることができます:

void myMethod1() {
    synchronized(this) {
        //your code
    }
}

このように示されているように、ロックが解除されるまで待たなければならないため、同期された 2 つのメソッドが互いにブロックする理由は明らかthisです。

于 2013-11-01T15:01:48.363 に答える
0

myMethod1myMethod2には、次のように異なるモニターを使用できます。

class MyClass {
    Object monitor1 = new Object();
    Object monitor2 = new Object();
    void myMethod1() {
        synchornized(monitor1) {
        //code 
        }
    }

    void myMethod2() {
        synchronized(monitor2) {
        //code
        }
    }
}
于 2013-11-01T15:02:34.343 に答える
0

はい、両方のメソッドを as として宣言するsynchronizedと、異なるデータ要素にアクセスする場合でも、互いにブロックされます。

これを回避するには、よりきめ細かいロックを使用できます。例えば:

class MyClass {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    void myMethod1() {
        synchronized (lock1) {
            //code 
        }
    }

    void myMethod2() {
        synchronized (lock2) {
            //code 
        }
}
于 2013-11-01T15:01:25.977 に答える