【发布时间】:2011-03-08 22:19:15
【问题描述】:
看起来在使用 Java 编程时,如果涉及线程,我们将不再使用 Vectors。
在使用线程时我应该使用什么类而不是 Vector?
import java.util.Vector;
Vector<String> v = new Vector<String>();
【问题讨论】:
标签: java multithreading vector thread-safety
看起来在使用 Java 编程时,如果涉及线程,我们将不再使用 Vectors。
在使用线程时我应该使用什么类而不是 Vector?
import java.util.Vector;
Vector<String> v = new Vector<String>();
【问题讨论】:
标签: java multithreading vector thread-safety
看起来在使用 Java 编程时,如果涉及线程,我们将不再使用 Vectors。
您需要了解为什么使用Vector 在大多数情况下被认为是一件坏事。原因是:
Vector 同步每个操作。大多数上下文不需要细粒度同步,因此这是不必要的性能开销。
Vector.elements() 方法返回一个没有快速失败语义的 Enumeration。
回到你的问题。替代方案取决于您的线程试图做什么:
如果用例根本不需要同步,请使用ArrayList 或LinkedList。在以下情况下,您通常会使用这些:
ArrayList,该类未在自定义类 API 中公开。如果用例需要细粒度同步,Collections.synchronizedList 包装器等效于Vector。或者,您可以坚持使用Vector 并避免使用elements() 操作。
CopyOnWriteArrayList 列表的优点是它的迭代器支持并发修改......在某种意义上。如果您的应用程序主要执行读取列表,它也可以更好地扩展。读取操作根本不需要显式同步,通常只需要读取单个volatile 一次。但另一方面是写操作确实是同步的,而且比“普通”ArrayList 更昂贵。
Vector 和Collections.synchronizedList 包装器的另一个问题是某些用例需要更粗略的同步;例如测试列表的大小并在单个同步操作中有条件地添加元素。 Queue 和 Deque 类提供了处理这种事情的更高级别的抽象......对于涉及将工作从一个线程异步传递到另一个线程的用例。
最重要的是,没有一种万能的解决方案。您需要了解应用程序设计的并发特性,并据此选择数据结构。
最后,如果您正在为 Java ME 编程,您可能无法使用 Vector,具体取决于您所针对的 J2ME 配置文件。
List<String> list = Collections.synchronizedList(new ArrayList<String>());
【讨论】:
Vector 的或多或少的插件替代品。但它不一定是正确的使用方法。
对于线程不安全的情况,使用ArrayList。
对于线程安全的情况,请使用最适合您的情况,CopyOnWriteArrayList、Queue、BlockingDeque 等。要获得更多建议,我们需要知道您如何使用您的集合来操作。
我建议不要使用 Collections.synchronizedList(...) 包装器,因为它可能无法很好地扩展(除非您不太关心可扩展性)。但这一切都取决于您的上下文。
【讨论】:
Collections.synchronizedList(...) 不能扩展吗?
数组,但如果你不知道大小,请使用 concurrentmap 的实现
【讨论】:
使用列表并像同步它们一样
List<?> list = Collections.synchronizedList(new ArrayList<?>());
【讨论】: