首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >地图内采集的同步

地图内采集的同步
EN

Stack Overflow用户
提问于 2017-05-13 22:47:32
回答 2查看 862关注 0票数 2

下面是演示这种情况的示例代码:

代码语言:javascript
复制
public class ConnectionRegistry {

    private ConcurrentMap<String, List<Connection>> registry = new ConcurrentHashMap<>();

    public List<Connection> find(String key) {
        List<Connection> connections = registry.get(key);
        if (null == connections) {
            return Collections.emptyList();
        }
        synchronized(connections) {
            return new ArrayList(originalCopy);
        }
    }

    public void register(String key, Connection connection) {
        List<Connection> connections = registry.get(key);
        if (null == connections) {
            List<Connection> newConnections = new ArrayList<>();
            connections = registry.putIfAbsent(key, newConnections);
            if (null == connections) {
                connections = newConnections;
            }
        }
        synchronized(connections) {
            connections.add(connection);
        }
    }

}

在上面的代码中,我有一个注册表来管理按键索引的连接。我希望使其线程安全,所以我使用了ConcurrentMap数据结构,除了映射,我希望确保映射中的List也是线程安全的,因此我使用了List关键字,如上面的源代码所示。

但是,我的IDE警告我,这是局部变量和上的一个同步,在使用时很难保证这种同步的正确性。

是否有其他方法或良好做法来处理这种情况?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-13 23:48:07

向量实现动态数组。它类似于ArrayList,但有两个不同之处:

  • 矢量同步。
  • 向量包含许多不属于集合框架的遗留方法。

并从文件中:

与新的集合实现不同,Vector是同步。如果不需要线程安全实现,建议使用ArrayList代替Vector.net。

只要做一些修改,代码将是:

代码语言:javascript
复制
public class ConnectionRegistry {

    private ConcurrentMap<String, List<Connection>> registry = new ConcurrentHashMap<>();

    public List<Connection> find(String key) {
        List<Connection> connections = registry.get(key);
        if (null == connections) {
            return Collections.emptyList();
        }

        return new Vector<Connection>(originalCopy);

    }

    public void register(String key, Connection connection) {
        List<Connection> connections = registry.get(key);
        if (null == connections) {
            List<Connection> newConnections = new Vector<Connection>();
            connections = registry.putIfAbsent(key, newConnections);
            if (null == connections) {
                connections = newConnections;
            }
        }

        connections.add(connection);

 }
票数 1
EN

Stack Overflow用户

发布于 2017-05-14 07:28:25

如果您需要一个同步列表,您可以调用Collections.synchronizedList()或使用上面answer.Vector中提到的向量,而同步ArrayList比它们的并发对应项CopyOnWriteArrayList慢得多,因为它锁定了整个集合,例如,即使它不允许多次读取,所以您可以考虑并发集合永远不会锁定整个Map或List。

它们通过使用锁剥离或在CopyOnWriteArrayList中使用的技术来实现线程安全,允许多个读取器线程在不同步的情况下进行读取,并且当写入发生时,它会复制整个ArrayList并与更新的线程交换。

如果-CopyOnWriteArrayList主要用于只读目的,那么ArrayList的性能很可能优于同步的ArrayList,但是如果它的读写混合,那么Collections.synchronizedList()也是好的。另一个不同之处在于它的迭代方式。

从同步-The返回的ArrayList是一个快速失败的迭代器,但是CopyOnWriteArrayList返回的迭代器是一个故障安全迭代器。

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

https://stackoverflow.com/questions/43958679

复制
相关文章

相似问题

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