Java线程对象锁

时间:2018-12-10 16:56:12

标签: java multithreading

据我了解,每个对象都有一个可以被当前线程持有的锁。

因此,基于此示例:

public class T1 {
    private final Object o = new Object();

    public  void m1() {
        synchronized(o) {
            //...wait some time
        }
    }
}

如果我创建类似这样的内容

    T1 subject1 = new T1();
    T1 subject2 = new T1();
    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            subject1.m1();
            subject2.m1();  
        }
    };

Thread t1 = new Thread(r1);
t1.start();

将有两个锁subject1.osubject2.o(我测试了它们是不同的实例),这意味着这两种方法将独立运行并且同时运行,在我的示例中,这两个方法都被执行了然后,它在释放锁之后,尽管subject1和subject2是具有不同锁的不同实例,但下一次运行。

为什么?

3 个答案:

答案 0 :(得分:2)

在您的示例中,您正在同一线程中依次运行两个方法。要并行执行它们,必须在单独的线程中运行它们。

T1 subject1 = new T1();
T1 subject2 = new T1();
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        subject2.m1();  
    }
};
Runnable r2 = new Runnable() {
    @Override
    public void run() {
        subject2.m1();  
    }
};

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();

答案 1 :(得分:1)

  

将有两个锁subject1.osubject2.o(我测试了它们   是不同的实例),这意味着两个方法都将运行   独立并同时

您说这两种方法将独立运行,尽管您只有一个封闭的方法来运行两个线程。相反,这两种方法必须位于不同的Runnable内才能同时执行。

T1 subject1 = new T1();
T1 subject2 = new T1();
Runnable r1 = subject1::m1;
Runnable r2 = subject2::m1;
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();

答案 2 :(得分:1)

  

将有两个锁subject1.osubject2.o ...,这意味着这两种方法将同时独立运行。

不。存在两个锁的事实 not 并不意味着对m1函数的两次调用将独立且同时运行。这仅意味着两个调用 可以同时运行。但这只有在这两个调用中的每个都发生在不同的线程中时才会发生。

这里已经尝试告诉您的其他答案是,您的代码不会从两个不同的线程进行两次调用。它使来自相同的线程的两个调用。您编写了以下run()方法:

public void run() {
    subject1.m1();
    subject2.m1();  
}

run()方法没有什么特别的。 YOU 编写了它,它的工作原理与您编写的任何其他方法完全相同:您编写的方法将首先调用subject1.m1(),然后在返回时将调用{{1 }}。

如果要并行进行这些呼叫,请执行@Palamino或@snr向您显示的操作。