gpt4 book ai didi

Java 线程安全 - 多个原子操作?

转载 作者:行者123 更新时间:2023-11-30 10:34:32 26 4
gpt4 key购买 nike

我只是一个想成为开发者的非开发者,所以我的问题可能非常简单!

我只是在测试 Java 多线程的东西,这不是真正的代码。我想知道如何在 Java 中同时更新两个成员变量,以防我们希望它们同步。例如:

public class Testing
{
private Map<String, Boolean> itemToStatus = new ConcurrentHashMap<>();
private Set<String> items = ConcurrentHashMap.newKeySet();

public static void main(String[] args)
{
(new Testing()).start("ABC");
}

public void start(String name) {
if (name.equals("ABC")) {
itemToStatus.put(name, true);
items.add(name);
}
}
}

在那种情况下(当然是想象多线程),我希望能够保证对 itemsitemToStatus 的任何读取总是返回相同的值。

因此,如果代码在 itemToStatus.put(name, true) 行中,并且其他线程询问 items.contains(name),它将返回 false .另一方面,如果另一个线程询问 itemToStatus.containsKey(name);,它将返回 true。我不希望那样,我希望它们都给出相同的值,如果这有意义的话?

如何使这两个更改原子化?这行得通吗?

if (name.equals("ABC")) {
synchronised(this) {
itemToStatus.put(name, true);
items.add(name);
}
}

不过,我不明白为什么会这样。我认为这是您需要锁或其他东西的情况?

干杯!

最佳答案

仅仅同步写入是行不通的。您还需要同步(在同一对象上)对 itemsitemToStatus 集合的读取访问。这样,如果另一个线程正在更新这两个集合,则没有线程可以读取任何内容。请注意,以这种方式同步意味着您不需要 ConcurrentHashMapConcurrentHashSet;普通的旧 HashMapHashSet 可以工作,因为您提供了自己的同步。

例如:

public void start(String name) {
if (name.equals("ABC")) {
synchronized (this) {
itemToStatus.put(name, true);
items.add(name);
}
}
}

public synchronized boolean containsItem(String name) {
return items.contains(name);
}

public synchronized boolean containsStatus(String name) {
return itemToStatus.containsKey(name);
}

这将保证 containsItem 返回的值也将由 containsStatus 返回,如果该调用已改为执行的话。当然,如果您希望返回值随时间保持一致(如首先调用 containsItem(),然后调用 containsStatus()),则需要更高级别的同步.

关于Java 线程安全 - 多个原子操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41620240/

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