Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当线程通过另一个类调用同步方法时会发生什么?_Java_Multithreading_Synchronization - Fatal编程技术网

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

Java 当线程通过另一个类调用同步方法时会发生什么?,java,multithreading,synchronization,Java,Multithreading,Synchronization,成为这个社区的一员感觉很好。我已经阅读了很多解答,消除了我对许多问题的疑虑,但没有找到一个解答。我知道Java中的同步是如何工作的,但当线程通过另一个类调用同步方法时,我很困惑地看到一个偏离的行为 PSB我所尝试的: 采用同步方法“meth1”的A类 运行项目的主类 package threadinterview; public class ThreadImpl { public static void main(String[] args) { final B b1 = new B()

成为这个社区的一员感觉很好。我已经阅读了很多解答,消除了我对许多问题的疑虑,但没有找到一个解答。我知道Java中的同步是如何工作的,但当线程通过另一个类调用同步方法时,我很困惑地看到一个偏离的行为

PSB我所尝试的:

采用同步方法“meth1”的A类

运行项目的主类

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();
}
}
现在在这个场景中,即使我最终运行了synchronized方法,我也看不到同步的效果。以下是我运行程序时得到的结果:

meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1
如果我也将同步方法设置为静态,那么我将获得类级锁,并可以看到同步效果。我真的不明白为什么类级锁定有效,但对象级在这种情况下不起作用。

每次调用

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

创建一个新的
对象<方法上的code>synchronized
在对象本身上同步此。因此,您正在不同对象上同步。一个同步调用不会阻止另一个同步调用,因为两个线程都有不同的监视器。

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

明白了。不是很难,但没有点击。非常感谢。:)
meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1
meth1: Thread-0
meth1: Thread-1
public void meth2() {
    A a1 = new A();
    a1.meth1();
}