synchronized方法与synchronized块

时间:2011-05-27 09:54:42

标签: java concurrency

如果我有以下代码

class SomeClass {    
...
public synchronized methodA() {
....
}

public synchronized methodB(){
....
}
}

这会在'this'对象上同步 但是,如果我的主要目标是确保多个线程不同时使用methodA(或methodB),但它们可以同时使用methodA和methodB, 那么这种设计是限制性的吗?因为这里thread1锁定对象(与对象关联的监视对象)以运行methodA,但同时thread2也在等待对象锁,即使methodA和methodB可以同时运行。
这种理解是否正确?

如果是,这是我们在私有虚拟对象上使用synchronized块的情况,这样methodA和methodB可以与不同的线程并行运行,但不能与不同线程的methodA(或methodB)并行运行。
谢谢。

3 个答案:

答案 0 :(得分:9)

你自己回答了这个问题:每个方法使用一个锁定对象,你就安全了。

private final Object lockA = new Object();
private final Object lockB = new Object();
public void methodA() {
    synchronized(lockA){
        ....
    }
}
public void methodB() {
    synchronized(lockB){
        ....
    }
}

对于更高级的锁定机制(例如ReentrantLock),请阅读Brian Goetz等人的Java Concurrency in Practice。您还应该阅读Effective Java by Josh Bloch,其中还包含有关使用synchronized

的一些内容

答案 1 :(得分:2)

如果要允许同时运行methodA()methodB()但是将每个方法限制为一个线程,则需要两个单独的对象进行同步。例如:

class SomeClass {
    private final Object lockA = new Object();
    private final Object lockB = new Object();

    public void methodA() {
        synchronized (lockA) {
            // 
        }
    }

    public void methodB() {
        synchronized (lockB) {
            // 
        }
    }
}

答案 2 :(得分:1)

如果我的理解是正确的,你想让线程T1同时运行methodA(),线程T2运行methodB() - 但你不希望线程T1同时运行methodA()线程T2运行methodA()(和methodB一样)对吗? 对于这种情况,您不能只使用一个简单的同步方法 - 相反,正如您所说,您将需要2个虚拟对象(一个用于methodA,一个用于方法B)来同步。或者您可以使用新的Lock类 - 每个方法一个Lock实例。