rob*_*nkc 2 java multithreading synchronization hashmap
在我的应用程序中,我需要维护一个存储器HashMap列表userIds以及它们的列表score.
有一个Writer Thread根据业务逻辑更新用户的分数.许多Reader Threads score从这张地图中读取用户,即map.get(userId).
列表userIds是静态的,即没有新用户添加到地图中.
按照JavaDoc If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally.
我没有进行任何结构改变(没有添加/删除).我是否需要使用ConcurrentHashMap或任何其他Synchronization构造用于此类用例?
您的map.put操作只会更新value字段HashMap$Node.这在HashMap结构一致性方面是安全的,但是在该value领域仍有数据竞争.如果您的值类型是一个简单的值类,如Integer,, Long或者Double,即使在数据竞争中也可以安全地取消引用它,但不能保证消费者会看到更新的分数.
一个干净的解决方法是更换您如Long与AtomicLong作为价值类型.然后你的地图永远不会被更新,只有它的值会以线程安全的方式变异.
这是解决方案的大纲:
安全发布地图:
volatile Map<Player, AtomicLong> scores;
void publishScores() {
scores = unmodifiableMap(createScoresMap());
}
Run Code Online (Sandbox Code Playgroud)更新分数:
void updateScore(Player p, long score) {
map.get(p).set(score);
}
Run Code Online (Sandbox Code Playgroud)阅读得分:
long getScore(Player p) {
return map.get(p).get();
}
Run Code Online (Sandbox Code Playgroud)