一、并发下,ArrayList类是不安全的
- 代码演示
package CollectionSafe; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * @author swaggyhang * @create 2023-07-02 17:26 */ public class Test01 { public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 1; i <= 10; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(list); }, String.valueOf(i)).start(); } } } - 上面代码会报错并发修改异常“java.util.ConcurrentModificationException”
二、解决方案
1. 使用Vector类【不推荐】
- Vector类的add方法是同步方法,但是效率很低

- 代码演示
package CollectionSafe; import java.util.List; import java.util.UUID; import java.util.Vector; /** * @author swaggyhang * @create 2023-07-02 17:26 */ public class Test01 { public static void main(String[] args) { // List<String> list = new ArrayList<>(); List<String> list = new Vector<>(); for (int i = 1; i <= 10; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(list); }, String.valueOf(i)).start(); } } }
2. 使用Collections工具类
-
使用Collections.synchronizedList()方法将普通的ArrayList类转换为安全的集合类

-
代码演示
package CollectionSafe; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; /** * @author swaggyhang * @create 2023-07-02 17:26 */ public class Test01 { public static void main(String[] args) { // List<String> list = new ArrayList<>(); // List<String> list = new Vector<>(); List<String> list = Collections.synchronizedList(new ArrayList<>()); for (int i = 1; i <= 10; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(list); }, String.valueOf(i)).start(); } } }
3. 使用CopyOnWriteArrayList类
-
写入时复制(简称:COW)是计算机领域的一种优化策略。底层源码如下:

-
多线程调用list时,读取的时候,是固定的,写入的时候,避免覆盖,造成数据问题(类似读写分离)
-
add()方法源码

-
代码演示
package CollectionSafe; import java.util.List; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; /** * @author swaggyhang * @create 2023-07-02 17:26 */ public class Test01 { public static void main(String[] args) { // List<String> list = new ArrayList<>(); // List<String> list = new Vector<>(); // List<String> list = Collections.synchronizedList(new ArrayList<>()); List<String> list = new CopyOnWriteArrayList<>(); for (int i = 1; i <= 10; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(list); }, String.valueOf(i)).start(); } } }
三、并发下,HashSet类是不安全的
-
HashSet本质就是HashMap,其构造器生成一个map对象

-
add()方法源码

-
代码演示
package CollectionSafe; import java.util.HashSet; import java.util.Set; import java.util.UUID; /** * @author swaggyhang * @create 2023-07-04 10:42 */ public class Test02 { public static void main(String[] args) { Set<String> set = new HashSet<>(); for (int i = 1; i <= 100; i++) { new Thread(() -> { set.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(set); }, String.valueOf(i)).start(); } } } -
上面代码会报错并发修改异常“java.util.ConcurrentModificationException”
四、解决方案
1. 使用Collections工具类
-
使用Collections.synchronizedSet()方法将普通的HashSet类转换为安全的集合类
package CollectionSafe; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.UUID; /** * @author swaggyhang * @create 2023-07-04 10:42 */ public class Test02 { public static void main(String[] args) { // Set<String> set = new HashSet<>(); Set<String> set = Collections.synchronizedSet(new HashSet<>()); for (int i = 1; i <= 100; i++) { new Thread(() -> { set.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(set); }, String.valueOf(i)).start(); } } }
2. 使用CopyOnWriteArraySet类
- CopyOnWriteArraySet底层还是使用CopyOnWriteArrayList那一套逻辑
package CollectionSafe; import java.util.Set; import java.util.UUID; import java.util.concurrent.CopyOnWriteArraySet; /** * @author swaggyhang * @create 2023-07-04 10:42 */ public class Test02 { public static void main(String[] args) { // Set<String> set = new HashSet<>(); // Set<String> set = Collections.synchronizedSet(new HashSet<>()); Set<String> set = new CopyOnWriteArraySet<>(); for (int i = 1; i <= 100; i++) { new Thread(() -> { set.add(UUID.randomUUID().toString().substring(0, 5)); System.out.println(set); }, String.valueOf(i)).start(); } } } - 构造器源码

- add()方法源码

五、并发下,HashMap类是不安全的
-
代码演示
package CollectionSafe; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @author swaggyhang * @create 2023-07-04 11:08 */ public class Test03 { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); for (int i = 1; i <= 10; i++) { new Thread(() -> { map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5)); System.out.println(map); }, String.valueOf(i)).start(); } } } -
上面代码会报错并发修改异常“java.util.ConcurrentModificationException”
六、解决方案
1. 使用Collections工具类
- 使用Collections.synchronizedMap()方法将普通的HashMap类转换为安全的集合类
package CollectionSafe; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @author swaggyhang * @create 2023-07-04 11:08 */ public class Test03 { public static void main(String[] args) { // Map<String, String> map = new HashMap<>(); Map<String, String> map = Collections.synchronizedMap(new HashMap<>()); for (int i = 1; i <= 10; i++) { new Thread(() -> { map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5)); System.out.println(map); }, String.valueOf(i)).start(); } } }
2. 使用ConcurrentHashMap类
-
代码演示
package CollectionSafe; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; /** * @author swaggyhang * @create 2023-07-04 11:08 */ public class Test03 { public static void main(String[] args) { // Map<String, String> map = new HashMap<>(); // Map<String, String> map = Collections.synchronizedMap(new HashMap<>()); Map<String, String> map = new ConcurrentHashMap<>(); for (int i = 1; i <= 10; i++) { new Thread(() -> { map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 5)); System.out.println(map); }, String.valueOf(i)).start(); } } } -
研究ConcurrentHashMap底层源码!!







![【数据结构与算法】将含有n个元素的整数数组A[0…n-1]的元素循环右移1≤m<n)位。要求算法的空间复杂度为O(1)。](https://img-blog.csdnimg.cn/0e4a9c7a3f7d4325a3fcbe145698b6d8.png)
![[MySQL]MySQL数据库基础](https://img-blog.csdnimg.cn/img_convert/fae5bf1d4fe0bd9963e7449f831c7aa8.png)










