首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步集合还是同步方法?

同步集合还是同步方法?
EN

Stack Overflow用户
提问于 2015-09-01 07:57:17
回答 5查看 1.1K关注 0票数 3

我有一个类容器,它包含一个集合,将由多个线程使用:

代码语言:javascript
复制
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方法

代码语言:javascript
复制
public synchronized void doSomeWithMap(String key, String value)

还是使用标准的线程安全装饰器?

代码语言:javascript
复制
Collections.synchronizedMap(map);
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-09-01 07:59:42

一般来说,同步地图将保护对它的大多数访问,而不必进一步考虑它。但是,“同步映射”对于迭代是不安全的,这可能是一个问题,取决于您的用例。在遍历其集合视图时,用户必须在返回的映射上手动同步。

如果符合您的用例,可以考虑使用ConcurrentHashMap

如果该对象有其他状态需要保护,以避免并发错误,则需要使用同步或Lock

票数 2
EN

Stack Overflow用户

发布于 2015-09-01 08:04:31

如果doSomeWithMap方法将多次访问映射,则必须对doSomeWithMap方法进行同步。如果唯一的访问是显示的put()调用,那么最好使用ConcurrentHashMap

请注意,“不止一次”是任何调用,迭代器本质上是许多“获取”。

票数 2
EN

Stack Overflow用户

发布于 2015-09-01 08:10:48

如果您查看SynchronizedMap的实现,您将看到它只是一个在调用任何方法之前使用互斥的非线程安全映射包装的映射。

代码语言:javascript
复制
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;
  }
}

如果您只想保护getput,那么这个实现可以帮助您。

但是,如果您想要一个可以迭代并由两个或多个线程更新的Map,则不适合,在这种情况下,应该使用ConcurrentHashMap

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32326416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档