ArrayList和Vector以及synchronizedList

本文探讨了ArrayList和Vector这两种数组型存储结构的区别。Vector的所有方法都采用synchronized关键字确保线程安全,而ArrayList则不具备这一特性。此外,文章还讨论了两者在扩容策略上的不同,并提到了如何使用synchronizedList来实现ArrayList的线程安全版本。

ArrayList和Vector都是使用数组方式存储数据

区别大概就是Vector本身所有方法都是用synchronized修饰的,所以线程安全,而ArrayList没有

还有一个区别就是新增元素的时候Vector的增量是原来的一倍,而ArrayList增加原来的一半

复制代码
public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
            if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }
复制代码

 

synchronizedList修饰的list如下

private static List<String> TEST_LIST = Collections.synchronizedList(new ArrayList<String>());

包裹了普通的ArrayList提供了线程安全的机制,类似Vector,所以到此为止synchronizedList与Vector的区别就是ArrayList与Vector的增量速度区别,所以需要线程安全操作时,增量比较快的时候推荐使用Vector,其他就没什么了

但是注意一点,

复制代码
* It is imperative that the user manually synchronize on the returned
     * list when iterating over it:
     * <pre>
     *  List list = Collections.synchronizedList(new ArrayList());
     *      ...
     *  synchronized(list) {
     *      Iterator i = list.iterator(); // Must be in synchronized block
     *      while (i.hasNext())
     *          foo(i.next());
     *  }
复制代码

synchronizedList在迭代的时候,需要开发者自己加上线程锁控制代码,为什么呢?

首先讲下为什么要手动加线程锁代码:

复制代码
    public boolean addAll(int index, Collection<? extends E> c) {
        synchronized(mutex) {return list.addAll(index, c);}
        }

    public ListIterator<E> listIterator() {
        return list.listIterator(); // Must be manually synched by user
        }
复制代码

因为迭代器涉及的代码没有在java api中没有加上线程同步代码

原因:整个迭代的过程中如果在循环外面不加同步代码,在一次次迭代之间,其他线程对于这个容器的add或者remove会影响整个迭代的预期效果,所以这里需要用户在整个循环外面加上synchronized(list)

### 一、线程安全性 在 Java 中,`Vector` 是一个线程安全的类,其所有方法都被 `synchronized` 修饰,这意味着在多线程环境中,`Vector` 可以保证数据的一致性完整性[^2]。相比之下,`ArrayList` 是线程安全的,其方法没有使用同步机制,因此在单线程环境下性能更优,但在多线程环境下需要额外的同步措施来确保线程安全。 ### 二、性能 由于 `Vector` 的方法都是同步的,这会导致在多线程环境中性能下降,因为线程同步会带来额外的开销。因此,在单线程环境下,`ArrayList` 的性能通常优于 `Vector`。`ArrayList` 的设计目标是提供更高的性能更低的内存占用,适用于大多数需要线程安全的应用场景。 ### 三、容量增长机制 当 `Vector` 或 `ArrayList` 中的元素超过其初始大小时,它们的容量增长机制有所同。`Vector` 在容量足时会将其容量翻倍,而 `ArrayList` 则只增加 50% 的大小。这种差异使得 `ArrayList` 在内存使用上更为高效,尤其是在数据量较大的情况下,能够更好地节约内存空间。 ### 四、同步机制 `Vector` 的同步机制使其在多线程环境中更加可靠,但这也意味着它在单线程环境下的性能如 `ArrayList`。如果在多线程环境中使用 `ArrayList`,可以通过外部同步机制(如使用 `Collections.synchronizedList()` 方法)来实现线程安全,从而在保证性能的同时获得所需的线程安全性。 ### 五、适用场景 - **Vector**:适用于多线程环境,尤其是需要线程安全的场景。尽管 `Vector` 的性能较差,但其线程安全性使其在某些特定的应用中仍然具有优势。 - **ArrayList**:适用于单线程环境或需要高性能的场景。`ArrayList` 的设计更注重性能内存效率,适合大多数需要线程安全的应用。 ### 示例代码 以下是一个简单的示例,展示了如何创建使用 `ArrayList` `Vector`: ```java import java.util.ArrayList; import java.util.Vector; public class Main { public static void main(String[] args) { // 创建 ArrayList ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("Element1"); arrayList.add("Element2"); System.out.println("ArrayList: " + arrayList); // 创建 Vector Vector<String> vector = new Vector<>(); vector.add("Element1"); vector.add("Element2"); System.out.println("Vector: " + vector); } } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值