我有一个类容器,它包含一个集合,将由多个线程使用:
public class Container{
private Map<String, String> map;
//ctor, other methods reading the map
public void doSomeWithMap(String key, String value){
//do some threads safe action
map.put(key, value);
//do something else, also thread safe
}
}更好的方法是声明synchronized方法
public synchronized void doSomeWithMap(String key, String value)还是使用标准的线程安全装饰器?
Collections.synchronizedMap(map);发布于 2015-09-01 07:59:42
一般来说,同步地图将保护对它的大多数访问,而不必进一步考虑它。但是,“同步映射”对于迭代是不安全的,这可能是一个问题,取决于您的用例。在遍历其集合视图时,用户必须在返回的映射上手动同步。
如果符合您的用例,可以考虑使用ConcurrentHashMap。
如果该对象有其他状态需要保护,以避免并发错误,则需要使用同步或Lock。
发布于 2015-09-01 08:04:31
如果doSomeWithMap方法将多次访问映射,则必须对doSomeWithMap方法进行同步。如果唯一的访问是显示的put()调用,那么最好使用ConcurrentHashMap。
请注意,“不止一次”是任何调用,迭代器本质上是许多“获取”。
发布于 2015-09-01 08:10:48
如果您查看SynchronizedMap的实现,您将看到它只是一个在调用任何方法之前使用互斥的非线程安全映射包装的映射。
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
public Set<Map.Entry<K,V>> entrySet() {
synchronized (mutex) {
if (entrySet==null)
entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
return entrySet;
}
}如果您只想保护get和put,那么这个实现可以帮助您。
但是,如果您想要一个可以迭代并由两个或多个线程更新的Map,则不适合,在这种情况下,应该使用ConcurrentHashMap。
https://stackoverflow.com/questions/32326416
复制相似问题