为什么Thread在引用发生变化时不释放锁定

时间:2017-08-22 08:28:51

标签: java multithreading

public class UThread implements Runnable {

    Object o;

    UThread(Object o) {
        this.o = o;
    }

    @Override
    public void run() {
        synchronized (o) {
            System.out.println("inside before change" + Thread.currentThread().getName());
            try {
                Thread.sleep(5000);
            } catch (Exception er) {
            }
            o = new Object();
            System.out.println("inside after change" + Thread.currentThread().getName());
            try {
                Thread.sleep(5000);
            } catch (Exception er) {
            }

        }
        System.out.println("outside " + Thread.currentThread().getName());

    }


}


public class main {
    public static void main(String str[]) {

        Object o = new Object();
        UThread uThread = new UThread(o);
        Thread th = new Thread(uThread);

        UThread uThread2 = new UThread(o);
        Thread th2 = new Thread(uThread2);

        th.start();
        try {
            Thread.sleep(1000);
        } catch (Exception er) {
        }
        th2.start();
    }
}

当我们执行它打印的代码时

在changeThread-0之前的内部 在changeThread-0之后的内部 外线程-0
在changeThread-1之前的内部 改变后的内部线程-1 在Thread-1之外

因此,当我更改对象时,为什么第二个线程没有锁定o

2 个答案:

答案 0 :(得分:4)

分配引用不会对基础对象产生任何影响。它所做的只是复制参考值而不触及或改变对象本身。例如,它不会释放锁也不应该。

e.g。

Object o2 = o;
synchronized(o) {
    o = new Object();
    // o2 is still locked
}
// o2 is not locked

答案 1 :(得分:2)

第二个线程已请求锁定o变量引用的原始对象(在main方法中创建并传递给两个UThread实例的构造函数)。

更改第一个线程的synchronized块内o的值并不会改变此线程已锁定o引用的原始对象的事实,第二个线程也是等着锁。