gpt4 book ai didi

java - 高性能线程安全编码

转载 作者:行者123 更新时间:2023-11-30 06:04:18 24 4
gpt4 key购买 nike

如何提高该 Java 代码的性能?

public class HiScores {
private final Map<String, AtomicInteger> hiScores = new HashMap<>();
public long setHighest(String player, int newScore){
AtomicInteger highest;
synchronized(hiScores){
highest=hiScores.get(player);
if(highest==null){
highest=new AtomicInteger(0);
hiScores.put(player,highest);
}
}
int score=Math.max(highest.intValue(), newScore);
highest.set(score);
return score;
}
public Map<String, AtomicInteger> getHiScores(){
Map<String, AtomInteger> copy;
synchronized(hiScores){
copy=new HashMap<>(hiScores);
hiScores.clear();
}
return copy;
}
public void resetScores(){
synchronized(hiScores){
hiScores.clear();
}
}
}

如果将 HashMap 替换为 ConurrentHashMap,还需要同步块(synchronized block)吗?

最佳答案

Are the synchronized blocks still required if the HashMap was replaced by a ConcurrentHashMap?

如果您不使用 computeIfAbsent,则确实需要它们(或类似)。您需要原子地执行此序列:

  highest = hiScores.get(player);
if (highest == null) {
highest = new AtomicInteger(0);
hiScores.put(player, highest);
}

如果你只是改变 hiScoresConcurrentHashMap (并删除 synchronized block ),然后存在竞争条件,两个线程更新同一条目并且同时将创建两个不同的 AtomicInteger对象....并且第一个的高分将会丢失。

这里还有另一个竞争条件:

   int score = Math.max(highest.intValue(), newScore);
highest.set(score);

就其本身而言,setHighest无需使用 synchronized 即可实现该方法...但是您必须显着更改代码。

<小时/>

其他方法也存在问题1

   copy = new HashMap<>(hiScores);
hiScores.clear();

如果您在没有外部同步的情况下执行这些操作中的任何一个,它们将不是原子的。作为一个序列,它们绝对不会是原子的……这是该方法所需要的。

不幸的是,我认为 getHiScores 没有解决方案或resetScores仅使用 ConcurrentHashMap没有 synchronized 。可以使用 AtomicReference同样,但它取决于方法所需属性的精确(例如形式/数学)规范

1 - 我被你反直觉的方法名称欺骗了,在第一次尝试回答时没有查看第二个和第三个方法的代码。

<小时/>

总结:

  1. 这件事比“还需要同步块(synchronized block)吗?”复杂得多。

  2. 如果您正在寻找通用答案或通用解决方案(即 HiScores 不是您的真实代码),您将找不到。正确性取决于实际需求和实际实现代码。

关于java - 高性能线程安全编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51680560/

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