当一个线程通过另一个类调用synchronized方法时会发生什么?

时间:2014-03-05 18:14:17

标签: java multithreading synchronization

很高兴成为这个社区的一员。已阅读了很多答案,清除了我对许多问题的怀疑,但没有找到一个。我知道Java中的同步是如何工作的,但是当线程通过另一个类调用synchronized方法时,看到偏差的行为很困惑。

PSB我的尝试:

A类,同步方法“meth1”。

package threadinterview;

public class A {
public synchronized void meth1()
{
    for(int i=0; i<3; i++)
    {
        System.out.println("meth1: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted: " + Thread.currentThread().getName());
        }
    }
}

B类非同步方法“meth2”

package threadinterview;

public class B {
public void meth2() {
    A a1 = new A();
    a1.meth1();
}
}

运行项目的主要类

package threadinterview;
public class ThreadImpl {
public static void main(String[] args) {
    final B b1 = new B();
    final B b2 = new B();

    new Thread(new Runnable() {

        @Override
        public void run() {
            b1.meth2();
        }
    }).start();

    new Thread(new Runnable() {

        @Override
        public void run() {
            b1.meth2();
        }
    }).start();
}
}

现在在这种情况下,即使我最终运行同步方法,我也看不到同步的效果。这是我运行程序时得到的结果:

meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1

如果我同步方法也是静态的,那么我得到类级别锁定并且可以看到同步效果。我真的不明白为什么类级锁定有效但对象级别在这种情况下不起作用。

2 个答案:

答案 0 :(得分:2)

每次致电

public void meth2() {
    A a1 = new A();
    a1.meth1();
}

创建一个新的A对象。该方法上的synchronizedthis上对象本身进行同步。因此,您正在同步不同的对象。一个同步调用不会阻止另一个同步调用,因为两个线程都会获得不同的监视器。

答案 1 :(得分:0)

我认为你误解了'同步效应'是什么。在您的示例中,您从两个单独的线程调用B.meth2()。此方法创建类A的新实例,然后调用A.meth1()。现在无论你试图在meth1()上强制执行什么锁定(从你的例子或描述中都不是很清楚),这是无关紧要的,因为你在类A的两个不同实例上调用它,即你是隐式使用两个不同的锁。