ArrayList是一种动态数组,可以动态的增加或删除元素。ArrayList和Vector都是用数组实现的,但二者存在一定的区别:
-
Vector是多线程安全的,而ArrayList则不是
Vector使用synchronized来实现同步,所以在性能上比不上ArrayList。 -
当空间不足时,Vector增加原空间的一倍(默认值),但ArrayList增加原空间的50%
-
Vector可以设置增长因子,而ArrayList不可以
在日常开发中,经常使用ArrayList,可以实现快速的随机访问。但在多线程环境下,必须采用一定的措施来解决ConcurrentModificationException问题。
ConcurrentModificationException
解决方法包括3种:
-
使用Vector代替ArrayList
其线程安全的实现方式是对所有操作都加上了synchronized关键字,这种方式严重影响效率;并且也不是完全安全。具体参考Why is Java Vector class considered obsolete or deprecated? -
使用CopyOnWriteArrayList
CopyOnWriteArrayList的写操作性能较差,而多线程的读操作性能较好。因为CopyOnWriteArrayList的实现方式是在写入时通过复制链表来实现,每次添加都需要复制,对内存消耗大;在写入时需要加synchronized保护,但读取时则不需要进行同步。
CopyOnWriteArrayList只能保证数据最终的一致性,但是读写分离时可能存在实时的不一致性。 -
使用Collections.synchronizedList
使用Collections.synchronizedList在部分关键方法中使用了synchronized进行同步;但注意在一些非原子操作时,仍需要使用synchronized。此时的锁对象需为Collections.synchronizedList自身。
Collections.synchronizedList的写操作性能比CopyOnWriteArrayList在多线程操作的情况下要好很多,而读操作因为是采用了synchronized关键字的方式,其读操作性能并不如CopyOnWriteArrayList。
可以根据不同的应用场景,选择不同的多线程安全实现类。
参考方法:
CopyOnWriteArrayList与Collections.synchronizedList的性能对比
聊聊并发-Java中的Copy-On-Write容器
【集合类型的并发】Collections.synchronizedList
网友评论