3

我有一个场景,其中未知数量的线程将元素添加到服务器上的集合中。此集合中的数据不必排序,也不会被迭代。这个集合只需要两个简单的操作:

  1. 添加元素(在某些情况下删除旧元素)
  2. 从集合中读取所有元素(不是一个一个,而是整个集合,以便对其进行序列化并将其发送给客户端。当然,这些元素也可以移动到另一个集合,然后再进行序列化。)

哪个集合最适合这个用例?我会选择ConcurrentHashMap,但不知道这个选择好不好。

编辑:我忘记了一个重要的要求:如果某个类型的元素已经在这个集合中并且添加了另一个相同类型的元素,那么在添加新元素之前应该删除旧元素。对于这个要求,我想使用哈希值来避免搜索。存储的对象很简单:它们包含唯一的用户名和一些字符串和整数。对象的用户名应该用作键。

4

4 回答 4

3

是的,ConcurrentHashMap适合这个。在映射中使用用户名作为键类型 ( K) 并使用关联的用户信息(“一些字符串和整数”)作为值类型 ( )。V用于put添加新的键值对、remove删除键值对以及entrySet获取容器中的所有键值对(如果这就是您所说的“从集合中读取所有元素”的意思)。

于 2013-06-08T20:22:58.857 回答
2

我认为最好使用的实际上是ConcurrentSkipListSet。原因:

迭代器是弱一致的,返回的元素反映了在迭代器创建时或之后的某个时间点的集合状态。它们不会抛出 ConcurrentModificationException,并且可以与其他操作同时进行。升序视图及其迭代器比降序视图更快。

这意味着您可以浏览整个列表并阅读所有项目,同时添加其他项目。它是完全并发的!

请注意,添加项目需要 O(logN) 时间。

于 2013-06-08T21:57:21.700 回答
1

我相信java.util.concurrent 中有一个并发列表实现。CopyOnWriteArrayList这对您的要求很有用。

或者您可以使用:

 List<Object> objList = Collections.synchronizedList(new ArrayList<Object>());
于 2013-06-08T15:53:44.417 回答
1

它不是标准库的一部分,但您可以使用这个并发双向链表。它的迭代器是弱一致的,不会抛出 a ConcurrentModificationException,或者您可以使用toArray并循环返回的数组。

于 2013-06-08T15:58:16.127 回答