如何解决同步映射线程的这种用法安全吗?
| 我有一个单例类,该类具有一个可以同时由多个线程访问的映射。有人可以检查下面的代码,并告诉我其线程是否安全? (注意:我不打算使用ConcurrentHashMap,并且很少调用printMap方法。) public class MySingleton{
private Map<String,String> cache = Collections.synchronizedMap(
new LinkedHashMap<String,String>());
public String getValue(String key){
return cache.get(key)
}
public void setValue(String key,String value){
cache.put(key,value);
}
public void printMap(){
synchronized(cache){
for(Entry<String,String> entry: cache.entrySet()){
println(\'key: \'+entry.getKey()+\',value: \' + value);
}
}
}
}
我的测试正在运行...但是我怀疑这段代码是否足够好以至于被称为“线程安全”。
我考虑的要点:
readValue和putValue方法不需要具有'synchronized \'块,因为我使用的是syncedMap
printMap应该具有synced块,因为for的javadoc表示我们应该在每次迭代之前同步Map实例。
http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html#synchronizedMap%28java.util.Map%29
任何帮助表示赞赏。
解决方法
是的,没关系。关键是,在进行迭代时,任何内容都将无法修改地图,因为无论如何
cache.put
最终都会在cache
上进行同步。
我个人更希望通过使用“ normal”哈希图并通过所有三种方法在同一对象(无论是映射还是其他)上进行同步来使它明确化,但是您应该可以。
(或者,您可以使用ConcurrentHashMap
开始。至少值得一看。)
,是的,它是线程安全的。每次对缓存的访问都是同步的(通过syncedMap获取和设置,并通过显式同步块获取printMap)
,是的,此类是线程安全的。
尽管要注意,即使是线程安全的类也要求真正安全地使用安全发布(没有安全发布,则不能保证其他线程在非初始化状态下看不到“ 2”,即“ 5”)。
但是在这种情况下,您可以通过使类不可变来消除安全发布的需要(final
关键字保证其他线程在cache
中看不到null
):
private final Map<String,String> cache = Collections.synchronizedMap( new LinkedHashMap<String,String>());
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。