Java 集合列表 Vector 和 Stack

问:什么是 Vector 和 Stack,各有什么特点?

答:Vector 是线程安全的动态数组,同 ArrayList 一样继承自 AbstractList 且实现了 List、RandomAccess、Cloneable、Serializable 接口,内部实现依然基于数组,Vector 与 ArrayList 基本是一致的,唯一不同的是 Vector 是线程安全的,会在可能出现线程安全的方法前面加上 synchronized 关键字,其和 ArrayList 类似,随机访问速度快,插入和移除性能较差(数组原因),支持 null 元素,有顺序,元素可以重复,线程安全。

Stack 是继承自 Vector 基于动态数组实现的线程安全栈,不过现在已经不推荐使用了,Stack 是并发安全的后进先出,实现了一些栈基本操作的方法(其实并不是只能后进先出,因为继承自 Vector,所以可以有很多操作,严格说不是一个栈)。其共同点都是使用了方法锁(即 synchronized)来保证并发安全的。

问:简单说说 ArrayList 和 Vector 的区别?

答:ArrayList 在默认数组容量不够时默认扩展是 1.5 倍,Vector 在 capacityIncrement 大于 0 时扩容 capacityIncrement 大小,否则扩容为原始容量的 2 倍。Vector 属于线程安全级别的,而 ArrayList 是非线程安全的。

问:为什么现在都不提倡使用 Vector 了?

答:因为 Vector 实现并发安全的原理是在每个操作方法上加锁,这些锁并不是必须要的,在实际开发中一般都是通过锁一系列的操作来实现线程安全,也就是说将需要同步的资源放一起加锁来保证线程安全,如果多个 Thread 并发执行一个已经加锁的方法,但是在该方法中又有 Vector 的存在,Vector 本身实现中已经加锁了,双重锁会造成额外的开销,即 Vector 同 ArrayList 一样有 fail-fast 问题(即无法保证遍历安全),所以在遍历 Vector 操作时又得额外加锁保证安全,还不如直接用 ArrayList 加锁性能好,所以在 JDK 1.5 之后推荐使用 java.util.concurrent 包下的并发类。此外 Vector 是一个从 JDK1.0 就有的古老集合,那时候 Java 还没有提供系统的集合框架,所以在 Vector 里提供了一些方法名很长的方法(如 addElement(Object obj),实际上这个方法和 add(Object obj) 没什么区别),从 JDK1.2 以后 Java 提供了集合框架,然后就将 Vector 改为实现 List 接口,从而导致 Vector 里有一些重复的方法。

fail-fast 机制是 java 集合 (Collection) 中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出 ConcurrentModificationException 异常,产生 fail-fast 事件。

你可能感兴趣的:(Java 集合列表 Vector 和 Stack)