14

Java 开发强调的一个模因总是使用 ArrayList 而不是 Vector。向量已弃用。这可能是真的,但 Vector 和 Hashtable 的优点是它们是同步的。

我正在使用一个高度并发的应用程序,使用像 Vector 这样同步的对象不是有好处吗?似乎他们有自己的位置?

4

6 回答 6

17

Vector 和 Hashtable 的问题在于它们仅在本地同步。它们不会在并发应用程序中中断(如损坏数据),但是,由于本地同步(例如 get 已同步,但仅在 get 返回之前),您将希望在诸如此类的情况下执行自己的同步作为对内容的迭代。现在,即使你的 put-method 需要一些额外的同步来配合迭代同步,你最终会遇到 Hashtable/Vector 双重同步的情况。

于 2009-01-17T17:52:30.193 回答
17

ConcurrentHashMap比Hashtable快得多。它是并发的,而不仅仅是同步的。它一次承认多个读者/作者。

虽然没有这样的“并发”数组列表。根据您的需要,CopyOnWriteArrayList可能是也可能不是您需要的。

于 2009-01-17T18:01:07.680 回答
13

如果您需要同步的 ArrayList 或 HashMap,您可以将它们包装起来。

List list = Collections.synchronizedList(new ArrayList(...));
Map m = Collections.synchronizedMap(new HashMap(...));

就我个人而言,我发现这些集合中的“同步”方法在繁重的线程代码中不是很有用。有一些更新的集合可以提供更多帮助,但大多数情况下我发现自己制作自己的同步对象并围绕它们进行同步,或者使用 java.util.concurrent 中的新锁

于 2009-01-17T17:53:46.120 回答
9

Vector同步有它的位置,但这不是和之间的唯一区别ArrayListVector每次超过其容量时,将其内部存储数组增长固定数量,同时将其ArrayList增长固定因子,这通常是一种更好的方法(因为它为追加项目提供了 O(1)的摊销成本)。

另请注意,Collections.synchronizedList()可用于在任何List实现上创建同步视图,因此您不必绑定到的特性Vector(例如,您可能需要同步LinkedList)。

于 2009-01-17T17:55:25.227 回答
3

您可以使用静态 Collections 方法将 List 或 Map 转换为同步版本:http: //java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#synchronizedList (java.util 。列表)

通常,您通常需要锁定的不仅仅是对列表或地图的单独调用。

于 2009-01-17T17:55:28.317 回答
0

在我看来,您需要 Collection 本身是线程安全的唯一时间是:

  • 如果集合从类外部可见(公共或默认范围)
  • 如果您要从方法返回集合的句柄
  • 如果集合是您班级的静态成员

所有这些在设计方面可能都是一个坏主意。

更好的方法是将集合本身​​设为私有或受保护,并通过同步方法访问它。对于静态成员,如果您需要这样做,单例将是更好的选择。

于 2009-01-17T17:58:42.100 回答