Java 使用threadsafe集合的多线程
我不明白下面的代码片段是如何实现线程安全的Java 使用threadsafe集合的多线程,java,multithreading,Java,Multithreading,我不明白下面的代码片段是如何实现线程安全的 class MapUser { Map<String,Integer> map = new ConcurrentHashMap<String,Integer> public void addToMap(String str, Integer val){ if(checkMagicString(str)){ map.put(str,val); } }
class MapUser {
Map<String,Integer> map = new ConcurrentHashMap<String,Integer>
public void addToMap(String str, Integer val){
if(checkMagicString(str)){
map.put(str,val);
}
}
private boolean checkMagicString(String str){
//some logic to check Magic
//this logic involved operation on the String parameter str i.e. subString,toCharArray etc
}
}
类映射用户{
Map Map=新的ConcurrentHashMap
公共void addToMap(字符串str,整数val){
如果(检查magicstring(str)){
地图放置(str,val);
}
}
私有布尔校验字符串(字符串str){
//检查魔法的一些逻辑
//该逻辑涉及对字符串参数str的操作,即subString、toCharArray等
}
}
注意addToMap方法由多个线程并发调用。我想确保线程安全性得到维护。通过使用ConcurrentHashMap,我可以确保线程将安全地向其添加值
然而,我不明白方法checkMagicString(stringstr)如何保持线程安全?唯一的方法是让它同步吗?还是应该使调用方方法addToMap同步?
请注意,我没有在checkMagicString方法中访问映射。即使您将
checkMagicString
设置为原子,它也不会使序列成为原子
if(checkMagicString(str)){
map.put(str,val);
}
原子,因为一个线程可以在if
检查和map.put
调用之间中断,因此可能会导致两个线程插入相同的字符串。您需要锁定整个序列以确保安全
编辑:如果上述行为是可接受的(即两个线程插入同一个键并覆盖该值)而且
checkMagicString
不在共享状态下运行,那么您的代码就可以正常运行。如果您想要的是原子操作,那么在这种情况下,最好确保checkMagicStr是原子的,并在映射上使用原子操作:
boolean done = false;
while(!done) {
Integer oldVal = map.get(str);
if (checkMagicStr(str) {
if (oldVal != null) {
done = value == map.replace(str, val, oldVal); // otherwise try again...
} else {
done = null == map.putIfAbsent(str, val); // otherwise try again...
}
} else {
done = true; // there's nothing to do...
}
}
您可能希望对while循环有一个限制,并在遇到异常时抛出一个异常,因为它可能在高度并发的系统上永远运行。从您的问题中不清楚为什么需要这些,b/c您所拥有的将是“线程安全的”,但这可能会有所帮助。我假设您正在访问
checkMagicString
内部的映射?如果没有,那么你很好。如果你是,那么请编辑你的帖子来展示这一点。这实际上取决于checkMagicString在做什么。只要它不访问映射,这两个操作就不必是原子操作来维护线程安全。@assylias:这两个操作不需要,但顺序应该是原子操作,因为我假设他不希望两个线程放置相同的字符串。你的意思是使用同步的addToMap方法吗?如果这是必需的,那么多线程有什么好处?@Tudor如果checkMagicString不访问映射,那么没有什么可以阻止连续两次调用将同一字符串放入映射中两次。因此,使这两个操作原子化并没有什么区别(但增加了不必要的争用)。@assylias:我同意,我是说,不管checkMagicString
s原子性如何,结果序列都不会是原子的。