背景
Q:今天遇到一个场景,我们业务需要使用批量的数据进行操作,但是别人的接口只支持一个一个的查,所以需要用多线程去查结果值组装成一个list再进行后期的业务逻辑实现。
实验
用哪个list呢?写了一个小demo
1. ArrayList
使用我们平常经常用的ArrayList进行测试
public class SetThread implements Runnable {
private List<Long> indeLong;
public SetThread(List<Long> indeLong) {
this.indeLong = indeLong;
}
@Override
public void run() {
for (int i = 0; i < 50000; i++) {
indeLong.add(Long.valueOf(i));
}
}
}
public class MyMain {
public static void main(String[] args) throws InterruptedException {
// 初始化一个数组
List<Long> sycList = new ArrayList<>(200000);
SetThread setRunnable1 = new SetThread(sycList);
Thread thread1 = new Thread(setRunnable1);
SetThread setRunnable2 = new SetThread(sycList);
Thread thread2 = new Thread(setRunnable2);
SetThread setRunnable3 = new SetThread(sycList);
Thread thread3 = new Thread(setRunnable3);
SetThread setRunnable5 = new SetThread(sycList);
Thread thread5 = new Thread(setRunnable5);
thread1.start();
thread2.start();
thread3.start();
thread5.start();
thread1.join(); // 主线程等待子线程执行完毕
thread2.join();
thread3.join();
thread5.join();
System.out.println(sycList.size());
}
}
但是返回的结果值不是我们预期的200000个
2. synchronizedList
再次使用线程安全的synchronizedList测试
public class MyMain {
public static void main(String[] args) throws InterruptedException {
// 初始化一个数组
List<Long> originList = new ArrayList<>();
List<Long> sycList = Collections.synchronizedList(originList);
SetThread setRunnable1 = new SetThread(sycList);
Thread thread1 = new Thread(setRunnable1);
SetThread setRunnable2 = new SetThread(sycList);
Thread thread2 = new Thread(setRunnable2);
SetThread setRunnable3 = new SetThread(sycList);
Thread thread3 = new Thread(setRunnable3);
SetThread setRunnable5 = new SetThread(sycList);
Thread thread5 = new Thread(setRunnable5);
thread1.start();
thread2.start();
thread3.start();
thread5.start();
thread1.join(); // 主线程等待子线程执行完毕
thread2.join();
thread3.join();
thread5.join();
System.out.println(sycList.size());
}
}
使用线程安全的List之后每次执行都是准确返回200000个
3. 运行抛出异常
中间还有个小插曲,使用ArrayList进行操作不设置最开始的initialCapacity值的测试
public class MyMain {
public static void main(String[] args) throws InterruptedException {
// 初始化一个数组(不设置数组长度)
List<Long> sycList = new ArrayList<>();
SetThread setRunnable1 = new SetThread(sycList);
Thread thread1 = new Thread(setRunnable1);
SetThread setRunnable2 = new SetThread(sycList);
Thread thread2 = new Thread(setRunnable2);
SetThread setRunnable3 = new SetThread(sycList);
Thread thread3 = new Thread(setRunnable3);
SetThread setRunnable5 = new SetThread(sycList);
Thread thread5 = new Thread(setRunnable5);
thread1.start();
thread2.start();
thread3.start();
thread5.start();
thread1.join(); // 主线程等待子线程执行完毕
thread2.join();
thread3.join();
thread5.join();
System.out.println(sycList.size());
}
}
抛出了异常: