gpt4 book ai didi

java - 如何修复 get/check/put 的非原子使用?

转载 作者:行者123 更新时间:2023-12-01 12:28:10 25 4
gpt4 key购买 nike

我有一个 JSONArray,我正在迭代它来填充我的 map ,如下所示。我的 ppJsonArray 将会有这样的数据 -

[693,694,695,696,697,698,699,700,701,702]

下面是我的代码,由于我的静态分析工具提示,该代码存在线程安全问题 -

Map<Integer, Integer> m = new HashMap<Integer, Integer>();
ConcurrentMap<String, Map<Integer, Integer>> partitionsToNodeMap = new ConcurrentHashMap<String, Map<Integer, Integer>>();
int hostNum = 2;

JSONArray ppJsonArray = j.getJSONArray("pp");
for (int i = 0; i < ppJsonArray.length(); i++) {
m.put(Integer.parseInt(ppJsonArray.get(i).toString()), hostNum);
}
Map<Integer, Integer> tempMap = partitionsToNodeMap.get("PRIMARY");
if (tempMap != null) {
tempMap.putAll(m);
} else {
tempMap = m;
}
partitionsToNodeMap.put("PRIMARY", tempMap);

但是当我运行静态分析工具时,它提示 -

Non-atomic use of get/check/put on partitionsToNodeMap.put("PRIMARY", tempMap)

这让我觉得我上面的代码不是线程安全的?我该如何解决这个问题?

最佳答案

上面的代码不是线程安全的。

它需要线程安全吗? (即,partitionsToNodeMap 是否被多个线程使用?是否可以有多个线程运行此例程?或者线程 A 线程是否可以在线程 B 运行此例程时在其他例程中更新partitionsToNodeMap?)

如果您对其中任何一个问题的回答为"is",那么您可能需要使用某种同步。

<小时/>

partitionsToNodeMap 是一个 ConcurrentHashMap。如果 map 结构同时被多个线程更新,这将防止 map 结构本身被破坏;但 map 中的数据可能不仅仅是随机字符串和整数。它可能对您的程序有某种意义。 map 结构本身不受损坏的事实并不能阻止 map 内容的高级含义被损坏。

<小时/>

Can you provide an example how can I protect this?

不是一个完整的,因为线程安全是整个程序的一个属性。您无法逐个函数执行线程安全。

线程安全就是保护不变量。。不变量是关于数据的断言,该断言必须始终为真。例如,如果您正在对大富翁游戏进行建模,则一个不变量会表示游戏中的总金额必须始终为 15,140 美元。

如果大富翁游戏中的某个线程通过从一名玩家那里拿走 X 美元并将其返还给银行来处理付款,则这是一个两步过程,并且在两个步骤之间,不变量被破坏/em>。如果第一个线程在两个步骤之间被抢占,并且其他某个线程计算了游戏中的所有金钱,那么它将得到错误的总数。

Java synchronized 关键字(或等效的 java.util.concurrent.locks.ReentrantLock 类)的主要用例是防止其他线程看到损坏的不变量。

任何一种锁定方式都是自愿的。为了使其工作,您必须将可以暂时破坏 protected block 中的不变量的每个代码块包装起来

synchronized(bank-lock) {
deductNDollarsFrom(N, player);
giveNDollarsTo(N, bank);
}

并且每个关心不变量的代码块也必须包装在 protected block 中。

synchronized(bank-lock) {
int totalDollars = countAllMoneyInGame(...);
if (totalDollars != 15140) {
throw new CheatingDetectedException(...);
}
}

Java 不会让余额转移和审计同时发生,因为它不允许两个线程同时在同一个对象(在本例中为银行锁)上同步。

你必须弄清楚你的不变量是什么。静态分析器告诉您 get()...put() 序列看起来像是一个可能关心不变量的代码块。你必须弄清楚它是否真的如此。是否有其他线程可以在 get() 和 put() 之间执行某些操作,从而导致事情出问题?如果是这样,那么两个代码块应该在同一个对象上同步,这样它们就不能同时执行。

关于java - 如何修复 get/check/put 的非原子使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26167150/

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