我写了一个以下的程序,根据我的理解它不应该打印
'Didn't hang, it should've.
因为shouldHang
方法是静态同步的,我已经进行了类级锁定。
我无法理解这种行为。有人可以帮我解决这个问题,
public class Test1 {
synchronized static public void shouldHang() {
System.out.println("Didn't hang, it should've.");
}
static public void main(String args[]) {
Test1 test = new Test1();
synchronized (test.getClass()) {
new Thread(new trylock()).start();
}
}
}
class trylock implements Runnable {
public void run() {
Test1.shouldHang();
}
}
答案 0 :(得分:4)
为什么不打印呢?您有一个线程调用单个同步方法。调用方法时,主线程已完成执行(因此释放了锁)。启动一个线程只是启动它并立即返回,所以事件的顺序是:
第二个线程可能尝试获取锁,而主线程仍然拥有它,但这不会改变任何东西:主线程释放它,从而使它可用于第二个线程。
答案 1 :(得分:1)
您的主线程在try-lock线程的整个生命周期内都没有锁定。你需要让主线程等待。然后你就会陷入僵局。这就是你想要的吗?
synchronized (test.getClass()) {
Thread t = new Thread(new trylock());
t.start();
t.join(); // Now the thread hang, but of course this will only deadlock your program.
}
答案 2 :(得分:0)
Thread.start启动给定的线程,然后立即返回;它不会等待新启动的线程完成。
在这种情况下,新线程会启动并被阻止,正如您所说;但是之后,主线程从start()方法返回并且synchronized块竞争,解除阻塞新线程并让它打印它的消息。
答案 3 :(得分:0)
为什么不打印?您的主线程仅使用锁来创建和启动第二个线程,然后释放锁。然后第二个线程获取锁并执行该方法。请注意,第二个线程可能确实在等待“非常微不足道”的时间,因此您没有看到它。
如果你真的想在这里看到 synchronized 的行为,请在你的线程起始块之后添加一个5秒的小睡眠。