我们经常使用的集合,首先了解ArrayList集合,首先它是一个线程不安全的在多线程的情况下操作可能会出现存入数据缺失或者什么的情况
ArrayList
是 Java 编程语言中的一个类,它实现了List
接口,是java.util
包中的一部分。ArrayList
是一个动态数组,这意味着它的大小可以在运行时根据需要增长或缩减。以下是关于ArrayList
的一些关键点:
动态大小:与传统的数组不同,
ArrayList
的大小不是固定的。当需要存储更多元素时,它会自动增长。同样,当元素被移除时,它的大小也会相应减小。实现
List
接口:ArrayList
实现了List
接口,因此它支持所有List
接口定义的操作,如添加、删除、访问和搜索元素。允许重复元素:
ArrayList
允许存储重复的元素。保持插入顺序:
ArrayList
保持元素的插入顺序,这意味着元素将按照它们被添加的顺序存储。非同步:
ArrayList
不是线程安全的。如果多个线程同时访问一个ArrayList
实例,并且至少有一个线程在结构上修改了列表,那么它必须在外部进行同步。快速访问:由于
ArrayList
是基于数组的,因此它提供了快速的随机访问。访问任何位置的元素的时间复杂度是 O(1)。插入和删除成本较高:在
ArrayList
中间插入或删除元素的成本较高,因为这可能需要移动其他元素。时间复杂度为 O(n)。常用方法:
add(E e)
:将指定元素添加到列表的末尾。add(int index, E element)
:在指定位置插入指定元素。get(int index)
:返回列表中指定位置的元素。remove(int index)
:移除列表中指定位置的元素。size()
:返回列表中的元素数量。初始容量:
ArrayList
有一个初始容量,当添加的元素超过这个容量时,列表会自动增长。可以通过构造函数指定初始容量。转换为数组:可以使用
toArray()
方法将ArrayList
转换为数组。
现在我们会在一个异步多线程的情况对数据库查询到的数据进行保存如集合
Lock lock = new ReentrantLock();
List<XXXX> xXXXs = new ArrayList();
for (Long count: counts) {
try {
manager.submit(()->{
//查询数据库
List<XXXX> xXXXList = xxxMapper.selectAll();
if (CollectionUtils.isNotEmpty(xXXXList )){
LOGGER.info("查询数据成功:{}", xXXXList .size());
lock.lock();
try {
xXXXs .addAll(xXXXList);
LOGGER.info("总共查询数据:{}", xXXXs .size());
} finally {
lock.unlock();
}
}
});
} catch (Exception e) {
LOGGER.error("查询数据失败:{}",e.getMessage(),e);
}
}