gpt4 book ai didi

java - 什么时候需要锁定

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

好吧,我知道这听起来可能很愚蠢(恐怕确实如此),但我对自己给出的答案并不完全满意,所以我认为在这里问这个问题是值得的。我正在处理一个关于并发性的练习(在 Java 中),它是这样的

Given a solved Sudoku chart, determine, using a fixed number of threads running at the same time, whether the chart has been correctly solved, i.e. no violation of the canonical rules occur (a number must appear within its row, its column, and its block only once).

现在我的问题是:由于线程只需要执行“读取”,从图表中收集信息并在其他地方详细说明它们,难道它们不能在不担心并发性的情况下工作吗? Chart 的状态始终是一致的,因为没有执行“写入”,因此它永远不会改变。

当且仅当存在资源一致性丢失的风险时,锁/同步块(synchronized block)/同步方法不是必需的吗?换句话说,我是否以正确的方式理解并发?

最佳答案

这是一个相当微妙的问题,一点也不愚蠢。

并发读取数据结构的多个线程可以在不同步的情况下这样做,仅当数据结构已安全发布时。这是内存可见性问题,而不是计时问题或竞争条件。

参见 Goetz 等人的第 3.5 节。 al., Java Concurrency In Practice,用于进一步讨论安全发布的概念。关于“有效不可变对象(immutable对象)”的第 3.5.4 节似乎适用于此,因为板在某个点变得有效不可变,因为它在达到已解决状态后永远不会被写入。

简而言之,写入线程和读取线程必须执行一些内存协调 Activity ,以确保读取线程对写入的内容有一致的看法。例如,编写器线程可以写入数独板,然后在持有锁的同时,将对板的引用存储在静态字段中。然后读取线程可以加载该引用,同时持有锁。一旦他们这样做了,他们就可以确信所有之前对板的写入都是可见且一致的。之后,读者线程可以自由访问板结构,无需进一步同步。

还有其他方法可以协调内存可见性,例如写入/读取 volatile 变量或 AtomicReference。使用更高级别的并发构造(例如锁存器或屏障),或将任务提交给 ExecutorService,也将提供内存可见性保证。

更新

基于与 Donal Fellows 的评论交流,我还应该指出,安全发布 要求也适用于从读者线程返回结果时。也就是说,一旦其中一个读取线程从其部分计算中获得了结果,它就需要将该结果发布到某处,以便它可以与其他读取线程的结果相结合。可以使用与以前相同的技术,例如在共享数据结构、volatiles 等上进行锁定/同步。但是,这通常不是必需的,因为结果可以从返回的 Future 中获得ExecutorService.submit调用。这些构造自动处理安全发布要求,因此应用程序不必处理同步。

关于java - 什么时候需要锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21800550/

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