gpt4 book ai didi

java - 关于避免 liveness failure 的疑惑——在 Effective Java 中讨论

转载 作者:搜寻专家 更新时间:2023-11-01 03:13:35 24 4
gpt4 key购买 nike

我指的是 Joshua Bloch Effective Java 的第 261 - 262 页

// Properly synchronized cooperative thread termination
public class StopThread {
private static boolean stopRequested;

private static synchronized void requestStop() {
stopRequested = true;
}

private static synchronized boolean stopRequested() {
return stopRequested;
}

public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested())
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}

Note that both the write method (requestStop) and the read method (stop- Requested) are synchronized. It is not sufficient to synchronize only the write method! In fact, synchronization has no effect unless both read and write operations are synchronized.

Joshua 的示例在this 上同步。但是我的疑问是,synchronized 必须作用于同一个对象吗?比如说,如果我将代码更改为

    private static void requestStop() {
synchronized(other_static_final_object_monitor) {
stopRequested = true;
}
}

private static synchronized boolean stopRequested() {
return stopRequested;
}

这还能避免 active 失败吗?

也就是说,我们知道在读/写期间为同一对象获取监视器可以避免 active 失败(根据 Joshua Bloch 的示例)。 但是在读/写期间为不同的对象抓取监视器怎么样?

最佳答案

我不相信这是有保证的,尽管如果它在所有现有实现中确实我也不会感到惊讶。 Java 语言规范,section 17.4.4声明如下:

An unlock action on monitor m synchronizes-with all subsequent lock actions on m (where subsequent is defined according to the synchronization order).

我相信在锁内读取/写入共享变量的所有安全性都源于规范中的要点 - 并且指定有关单个监视器上的锁定和解锁操作的任何内容。

编辑:即使这确实适用于单个变量,您也不想将它用于多个变量。如果您在拿着监视器时更新多个变量并且在拿着监视器时只从它们读取,您可以确保您始终读取一组一致的数据:在您完成之前没有任何东西会写入变量 Y阅读它,但在您读取变量 X 之后。如果您使用不同的监视器进行读取和写入,那么一致性就会消失:在您读取它们时,值可以随时更改。

关于java - 关于避免 liveness failure 的疑惑——在 Effective Java 中讨论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4744085/

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