ArrayList数据结构:
底层数据结构就是一个数组,元素类型都是object类型,对ArrayList的所有操作底层都是基于数组。
ArrayList的线程安全性:
对ArrayList集合进行元素添加是时候是分两个步骤:
1.在object[size]的位置进行元素添加。
2.元素添加完成size的值加1。
但是在多线程的环境下不保证具有原子性。
为什么不安全?
举例:在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;而 如果是在多线程情况 下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程B得到运行的机会。线程B也向 此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完 成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线 程B都继续运行,都增 加 Size 的值。那好,现在我们来 看看ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
加粗样式
ArrayList怎么解决线程安全:
1.java.util.Collections.SynchronizedList
但是它所有方法都是带同步对象锁的,和 Vector 一样,它不是性能最优的
2.并发包下:java.util.Concurrent.CopyOnWriteArrayList
写操作在一个复制的数组上进行,读操作在原数组中进行,读写分离互不影响(缺点是:读的数据可能不是时时的数据,正在写入的时候读的是之前数组的数据);
写操作需要加锁,防止并发写入时导致写入数据丢失;
写操作结束后需要把原数组指向新的复制数组。