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
。
答案 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
引用的原始对象的事实,第二个线程也是等着锁。