Java 集合框架常用实现对比
在 Java 开发面试中,集合框架的底层原理和线程安全机制是高频考点。以下针对常见的 List 实现类及线程控制方法做详细梳理。
ArrayList 与 LinkedList 比较
数据结构差异
- ArrayList:基于动态数组实现。内存地址连续,一旦数据确定,查询效率较高(支持随机访问)。
- LinkedList:基于双向链表实现。内存地址不连续,开辟空间时不需要连续地址,适合频繁新增和删除操作。
性能特征
- 插入/删除:ArrayList 需要移动后续元素,效率较低;LinkedList 只需修改指针,优势明显。
- 查询:ArrayList 支持 O(1) 时间复杂度的索引访问;LinkedList 需遍历节点,查询性能较差。
适用场景
- 若业务侧重于随机读取数据,优先选用 ArrayList。
- 若业务侧重于频繁的增删改操作,LinkedList 更为合适。
ArrayList 与 Vector 比较
线程安全性
- Vector:所有方法均使用
synchronized修饰,天然线程安全。但锁机制导致并发性能下降。 - ArrayList:非线程安全,但在单线程环境下性能优于 Vector。
扩容机制
- 当容量不足时,Vector 会将容量翻倍(2 倍)。
- ArrayList 则增加原容量的 50%。
- 从内存利用率角度考虑,ArrayList 通常更优。
注意:大多数现代开发场景推荐使用 ArrayList,配合外部同步机制或并发容器(如 CopyOnWriteArrayList)来满足线程安全需求,而非直接使用 Vector。
线程安全字符串处理类比
与 Vector 类似,StringBuffer 也是线程安全的可变字符序列,适用于多线程环境下的缓冲区操作;而 StringBuilder 仅用于单线程,性能更高。String 本身是不可变的,适用于少量字符串操作。
wait() 与 sleep() 的区别
这两个方法都用于暂停当前线程的执行,但本质区别在于锁的处理。
-
所属类不同
sleep()属于Thread类。wait()属于Object类。
-
锁的释放行为
- sleep():让出 CPU 时间片给其他线程,但不会释放对象锁。调用期间线程保持监控状态,时间结束后自动恢复。
- wait():线程会放弃对象锁,进入该对象的等待池(Wait Set)。只有当其他线程对该对象调用
notify()或notifyAll()后,本线程才会重新竞争获取锁并进入运行状态。
-
使用限制
wait()必须在同步代码块或同步方法中调用,否则会抛出IllegalMonitorStateException。sleep()无此限制。


