同步块问题?

时间:2012-06-29 12:35:12

标签: java multithreading synchronization

您好我有一个有多种方法的类,我需要在所有方法中使用synchronized块:

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 synchronized块。我想知道我该怎么做才能删除它?我应该为每个要使用的方法创建成员变量,还是有其他方法可以解决这个问题?

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

4 个答案:

答案 0 :(得分:4)

您应该在方法2方法中使用另一个互斥锁。

答案 1 :(得分:4)

根据您的评论判断我假设您希望每个方法同步而不是每个对象。在这种情况下,最简单的方法是为每个方法声明一个单独的监视器对象,即mutex1mutex2等。

答案 2 :(得分: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
    }
}

如果您有很多方法,也可以将它们打包成阵列。

答案 3 :(得分: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();
    }
}