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
    }
}

我正在使用互斥锁来同步块,所以如果method1正在使用会发生什么,另一个method2同步块等待直到流从method1.

我不希望这种情况发生,那我该怎么办?我知道因为我对所有方法都使用互斥锁,所以它会锁定method2同步块。我想知道我应该怎么做才能删除它?我应该为每个要使用的方法创建成员变量,还是有另一种解决方法?

我希望另一个线程只有在调用相同的方法时才等待。就像两个线程类 mehod1 一样,所以第二个线程应该等待。但如果第二个线程调用 method2 它不应该等待。

4

4 回答 4

4

您应该在 method2 方法中使用另一个 mutext。

于 2012-06-29T12:42:36.413 回答
4

从您的评论来看,我假设您想要按方法同步而不是按对象同步。在这种情况下,最简单的方法是为每个方法声明一个单独的监视器对象,即mutex1,mutex2等。

于 2012-06-29T12:42:49.623 回答
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()

public Test() {
    for(int i = 0; i < mutexes.length()) {
        mutexes[i] = new Object();
    }
}
于 2012-06-29T12:48:56.037 回答
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 回答