在java中使用synchronized块可以一次阻止对多个方法的访问

时间:2012-07-19 21:32:53

标签: java multithreading synchronization

如果我有两种方法:

public class A {

    public void doSomething() {
        synchronized(A.class) {
            //synchronized block here
        }
    }

    public void doSomethingElse() {
        synchronized(A.class) {
           //synchronized block here
        }
    }
}

所以我的问题是,A.class是否像全球锁定一样?意思是一个执行方法doSomething()的线程被阻塞而另一个线程正在执行doSomethingElse()

谢谢。

3 个答案:

答案 0 :(得分:3)

  

A.class就像全局锁?

任何synchronized块都会锁定特定对象。锁定A.class充当您正在运行的ClassLoader的“全局”锁定,因为Java保证每个加载器中只有一个A.class对象实例。 A.class是一个对象,就像new A()是一个对象。

锁定A.class与锁定静态方法相同:

public class A {
    public static synchronized void someStaticMethod() {
        // in here you are locked on A.class as well
    }
    public void doSomething() {
        synchronized (A.class) {
            // this block is locked on the same object as someStaticMethod()
        }
    }
}

为了进行比较,当您锁定实例方法(而不是静态方法)时,它与锁定正在执行的A实例相同。换句话说this

public class A {
    public synchronized void someInstanceMethod() {
        // in here you are locked on the instance of A (this)
    }
    public void doSomething() {
        synchronized (this) {
            // this block is locked on the same instance of A
        }
    }
}

同样,它是关于特定对象的问题。这是Java documentation about locks

答案 1 :(得分:1)

您的示例将锁定所有获取由同一类加载器加载的A类的所有实例中的锁定的方法中的线程,因此,如果任何一个线程获取阻止所有其他线程的锁定访问该对象或该类的任何其他对象上的任何方法的线程。通常设置这样的东西可能是个坏主意。锁将不必要地粗粒化(导致线程等待,即使它们只想访问属于不存在共享的不同实例的数据)并且会过度地限制并发。如果您的设计确实需要这个,那么您应该质疑您的设计。

答案 2 :(得分:0)

它会被对象锁定,所有其他线程将被阻塞,直到current thread releases the lock。根据java规范:

  

synchronized方法在执行之前获取监视器(第17.1节)。   对于类(静态)方法,与类关联的监视器   使用方法类的对象。对于实例方法,   与此关联的监视器(方法所针对的对象)   使用