0

こんにちは私は次のようなすべてのメソッドで同期ブロックを必要とする複数のメソッドを持つクラスを持っています:

public class Test2 {
    private Object mutex=new Object();
    private OtherClass obj=new OtherClass();

    public void method1(){
        //do some stuff
        synchronized (mutex) {
            obj.//some method
            //do some stuff
        }
        //do other stuff
    }

    public void method2(){
        //do some stuff
        synchronized (mutex) {
            obj.//some method
            //do some stuff
        }
        //do other stuff
    }

    public void method3(){
        //do some stuff
        synchronized (mutex) {
            obj.//some method
            //do some stuff
        }
        //do other stuff
    }

    public void method4(){
        //do some stuff
        synchronized (mutex) {

            obj.//some method
            //do some stuff
        }
        //do other stuff
    }
}

私はmutexを使用してブロックを同期しているので、使用されている場合はどうなりますかmethod1。他のmethod2同期されたブロックは、フローがの同期されたブロックから出るまで待機しmethod1ます。

これを起こしたくないので、どうすればよいですか?method2すべてのメソッドにmutexを使用しているので、同期されたブロックがロックされることを知っています。これを削除するにはどうすればよいですか?使用するメソッドごとにメンバー変数を作成する必要がありますか、それともこれを回避する別の方法がありますか?

同じメソッドが呼び出された場合にのみ他のスレッドを待機させたい..2つのスレッドがmehod1をクラス化する場合のように、2番目のスレッドは待機する必要があります。ただし、2番目のスレッドがmethod2を呼び出す場合は、待機しないでください。

4

4 に答える 4

4

method2メソッドでは別のmutextを使用する必要があります。

于 2012-06-29T12:42:36.413 に答える
4

コメントから判断すると、オブジェクトごとではなくメソッドごとの同期が必要だと思います。この場合、最も簡単な方法は、メソッドごとに個別のモニターオブジェクトを宣言することmutex1ですmutex2

于 2012-06-29T12:42:49.623 に答える
2

メソッドごとに異なるモニターを使用するだけです。

public class Test2 {
    private Object mutex1 = new Object(), mutex2 = new Object();
    private OtherClass obj=new OtherClass();

    public void method1() {
        //do some stuff
        synchronized (mutex1) {
            obj.//some method
            //do some stuff
        }
        //do other stuff
    }

    public void method2() {
        //do some stuff
        synchronized (mutex2) {
            obj.//some method
            //do some stuff
        }
        //do other stuff
    }
}

多くのメソッドがある場合は、それらを配列にパックすることもできます。

于 2012-06-29T12:43:12.960 に答える
2

mutexこれを実現して同期する場合は、メソッド呼び出しごとに(コード内で)異なるモニターオブジェクトを使用する必要があります。多くのメソッドがある場合は、ある種のコレクションを使用してミューテックスオブジェクトを保持できます。

public class Test2 {
    private Object[] mutexes=new Object[2];
    private OtherClass obj=new OtherClass();

    private synchronized Object getMutex(int i) {
        if(mutexes[i] == null) {
            mutexes[i] = new Object();
        }
        return mutexes[i];
    }

    public void method1(){
        //do some stuff
        synchronized (getMutex(1)) {
           //do some stuff
        }
        //do other stuff
    }

    public void method2(){
        //do some stuff
        synchronized (getMutex(2)) {
            //do some stuff
        }
        //do other stuff
    }
}

メソッドごとに同期するが、各メソッドがブロックobjから同じオブジェクト(この場合)synchronizedにアクセスする場合でも、その特定のオブジェクトへのアクセスはスレッドセーフではないことに注意してください。

getMutex()もう1つのオプションは、メソッドでオンデマンドでミューテックスを作成するのではなく、コンストラクターですべてのミューテックスを初期化することです。

public Test() {
    for(int i = 0; i < mutexes.length()) {
        mutexes[i] = new Object();
    }
}
于 2012-06-29T12:48:56.037 に答える