在类中使用同步方法组合的线程行为

时间:2010-12-20 14:24:00

标签: java synchronization thread-safety

<案例1

我有2个同步方法,如下所示:

class A {
    public void synchronized methodA() {}
    public void synchronized methodB() {}
}

A:我有线程T1和T2。线程是否可以同时执行属于类A的相同实例的methodAmethodB

  • 我的分析:答案是,因为线程T1只执行一个方法,线程T2将被阻止,直到T1完成执行。

B:我有线程T1和T2。线程是否可以同时执行属于类A的不同实例的methodAmethodB

  • 我的分析:答案是,因为T1和T2可以执行属于A类不同实例的methodAmethodB,并且不会被阻止。

根据我对案例1的分析,我的理解是否正确?

更新:案例2

我有2个同步方法,一个是非静态的,另一个是静态的。

class A {        
    public void synchronized methodA() {}    
    public void static synchronized methodB() {}    
}       

A:我有线程T1和T2。线程是否可以同时执行属于类A的相同实例的methodAmethodB

  • 我的分析:答案是没有因为T1只执行一个方法,T2将被阻止,直到T1完成执行。

B:我有线程T1和T2。线程是否可以同时执行属于类A的不同实例的methodAmethodB

  • 我的分析:答案是,因为T1和T2可以执行属于不同实例的methodAmethodB,但不会被阻止。

根据我对案例2的分析,我的理解是否正确?

2 个答案:

答案 0 :(得分:4)

案例A:否

案例B:是

您的分析是正确的。实例方法上的synchronized关键字在功能上等同于:

public void someMethod() {
   synchronized(this) {
      //code
   }
}

由于this在两个上下文中不同,因此它们不是互斥的。请注意,对于两个不同的实例,即使是相同的方法也可以同时调用。

修改

对于案例2,您在2A上不正确;它甚至没有意义。静态同步方法不属于该类的实例;如果它确实它不会是静态的!它不会在类的任何实例上进行同步(它没有引用要同步的实例!),因此它会在A的类对象上进行同步。类A中的静态同步方法等同于:

public static void methodB() {
   synchronized (A.class) {
      //code
   }
}

您的实例方法将在我上面显示的实例上进行同步,因此两个线程可以并行运行。

如果是B,那么显然它们也可以并行运行但你仍然缺少静态方法与任何实例无关的基本概念。

答案 1 :(得分:0)

案例1:你是对的。

每个Java对象都有(除其他外)相关的互斥锁(互斥锁)。当synchronized应用于非静态方法时,它是被锁定的实例的互斥锁。因此synchronized方法基于每个对象工作。

静态synchronized方法使用Class对象的锁,因此基于每个类(模数ClassLoader)进行操作,并且独立于非静态方法。您还可以在方法体中使用synchronized()来使用您希望的任何对象的锁定。

案例2:您不正确,因为methodA()和methodB()使用不同的互斥锁,如上所述。