ArrayList与单线程应用程序中的Vector性能

时间:2015-06-18 06:57:44

标签: java vector arraylist collections

我只是在寻找为什么ArrayList比Vector更快的问题的答案,我发现ArrayList更快,因为它没有同步。 所以我怀疑是:

  1. 如果ArrayList未同步,我们为什么要在多线程环境中使用它并将其与Vector进行比较。

  2. 如果我们处于单线程环境中,那么Vector的性能如何降低,因为我们正在处理单个线程时没有进行同步。

  3. 考虑到以上几点,我们为什么要比较性能?

    请指导我:)

4 个答案:

答案 0 :(得分:2)

  1. a)可以同步在多线程程序中使用ArrayList的方法。

    类X {

    List l = new ArrayList();
    
    synchronized void add(Object e) {
        l.add(e);
    }
    ...
    

    b)我们可以使用ArrayList而不将它暴露给其他线程,这是当ArrayList仅从局部变量引用时

    void x(){     List l = new ArrayList(); //没有其他线程除了当前可以访问l     ...

  2. 即使在单线程环境中输入同步方法也会锁定,这就是我们失去性能的地方

    public synchronized boolean add(E e) { // current thread will take a lock here
        modCount++;
    

    ...

答案 1 :(得分:1)

如果列表未在线程之间共享,则可以在多线程环境中使用ArrayList

如果列表在线程之间共享,则可以同步对该列表的访问。

否则,您可以使用Collections.synchronizedList()来获取可以安全使用线程的List。

Vector是不再使用的同步List的旧实现,因为内部实现基本上同步每个方法。通常,您希望同步操作序列。另外,在迭代列表时,你可以抛出一个ConcurrentModificationException,另一个线程会修改它。另外从性能的角度来看同步每个方法都不好。

另外在单线程环境中访问同步方法需要执行一些操作,因此在单个线程应用程序中Vector也不是一个好的解决方案。

答案 2 :(得分:1)

仅仅因为组件是单线程的并不意味着它不能在线程安全上下文中使用。您的应用程序可能拥有自己的锁定,在这种情况下,额外的锁定是多余的工作。

相反,仅仅因为组件是线程安全的,它并不意味着您不能以不安全的方式使用它。通常,线程安全性扩展到单个操作。例如。如果你拿一个Iterator并在一个集合上调用next(),这是两个操作,当它们组合使用时它们不再是线程安全的。你仍然需要使用锁定Vector。另一个简单的例子是

private Vector<Integer> vec = 

vec.add(1);
int n = vec.remove(vec.size());
assert n == 1;

这至少是三次操作,但是可能出错的事情数量远远超出您的想象。这就是为什么你最终做自己的锁定以及为什么Vector内部的锁定可能是多余的,甚至是不需要的。

为了你自己的利益;

  • vec可以随时更改另一个Vector或null
  • 任何操作,更改大小和最后一个元素之间都可能发生
  • vec.add(2)
  • 任何操作之间都可能发生
  • vec.remove()
  • vec.add(null)可能会在导致可能NullPointerException
  • 的任何操作之间发生

这些地方的vec可以/* change */

private Vector<Integer> vec = 

vec.add(1); /* change*/
int n = vec.remove(vec.size() /* change*/);
assert n == 1;

简而言之,假设仅仅因为您使用了线程安全集合,您的代码现在是线程安全的,这是一个很大的假设。

破坏的常见模式是

for(int n : vec) {
   // do something.
}

看起来无害,除了

for(Iterator iter = vec.iterator(); /* change */ vec.hasNext(); ) {
   /* change */ int n = vec.next();

我标记了/* change */,其他线程可以更改集合,这意味着此循环可以获得ConcurrentModificationException(但可能不会)

  

没有同步

JVM不知道不需要同步,因此它仍然需要做一些事情。它有一个优化,以降低无竞争锁的成本,但它仍然必须工作。

答案 3 :(得分:0)

您需要了解基本概念才能知道上述问题的答案......

当你说数组列表不同步且vector是,我们的意思是这些类中的方法(如add(),get(),remove()etc ... )是同步的在vector类中而不是在数组列表类中。这些方法将根据存储的数据进行操作。

因此,矢量类中保存的数据不能被并行编辑/读取,因为add,get,remove metods是同步的,并且数组列表中的相同内容可以并行完成,因为数组列表中的这些方法不同步...

这个并行活动使数组列表快速且向量缓慢...虽然您在多线程(或)单线程环境中使用它们,但这种行为仍然相同...

希望这能回答你的问题...