List的线程安全
- 背景
- 实验
- 1. ArrayList
- 2. synchronizedList
- 3. 运行抛出异常
- ArrayIndexOutOfBoundsException异常原因
背景
Q:今天遇到一个场景,我们业务需要使用批量的数据进行操作,但是别人的接口只支持一个一个的查,所以需要用多线程去查结果值组装成一个list再进行后期的业务逻辑实现。
实验
用哪个list呢?写了一个小demo
1. ArrayList
使用我们平常经常用的ArrayList进行测试
public class SetThread implements Runnable {private List<Long> indeLong;public SetThread(List<Long> indeLong) {this.indeLong = indeLong;}@Overridepublic 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());}
}
抛出了异常: