gpt4 book ai didi

Java等待()/加入(): Why does this not deadlock?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:19:02 27 4
gpt4 key购买 nike

给定以下 Java 代码:

public class Test {

static private class MyThread extends Thread {
private boolean mustShutdown = false;

@Override
public synchronized void run() {
// loop and do nothing, just wait until we must shut down
while (!mustShutdown) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Exception on wait()");
}
}
}

public synchronized void shutdown() throws InterruptedException {
// set flag for termination, notify the thread and wait for it to die
mustShutdown = true;
notify();
join(); // lock still being held here, due to 'synchronized'
}
}

public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();

try {
Thread.sleep(1000);
mt.shutdown();
} catch (InterruptedException e) {
System.out.println("Exception in main()");
}
}
}

运行它会等待一秒钟,然后正确退出。但这出乎我的意料,我预计这里会发生死锁。

我的推理如下:新创建的 MyThread 将执行声明为“synchronized”的 run(),以便它可以调用 wait() 并安全地读取“mustShutdown”;在 wait() 调用期间,锁被释放并在返回时重新获取,如 wait() 的文档中所述。一秒钟后,主线程执行 shutdown(),它再次同步,以便在另一个线程读取它的同时不访问 mustShutdown。然后它通过 notify() 唤醒另一个线程,并通过 join() 等待它完成。

但在我看来,另一个线程不可能从 wait() 返回,因为它需要在返回之前重新获取线程对象上的锁。它不能这样做,因为 shutdown() 在 join() 内部时仍然持有锁。为什么它仍然可以正常工作并正常退出?

最佳答案

join() 方法在内部调用 wait(),这将导致释放(Thread 对象的)锁。

参见下面的 join() 代码:

public final synchronized void join(long millis) 
throws InterruptedException {
....
if (millis == 0) {
while (isAlive()) {
wait(0); //ends up releasing lock
}
}
....
}

为什么您的代码看到这个而不是一般情况下看到的原因::您的代码看到这个而不是通常没有观察到的原因是因为 join() 方法在 < strong>Thread 对象 本身并因此放弃对 Thread 对象本身的锁定,并且由于您的 run() 方法也在同一个 Thread 对象上同步,您会看到这种意想不到的情况。

关于Java等待()/加入(): Why does this not deadlock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7246034/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com