JUC练习5——解决List,Set,Map多线程下的同步安全问题
1,对List进行优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; public class JucTest3 { public static void main(String[] args) { /** * 在多线程下ArrayList不安全会发生同步修改异常ConcurrentModificationException * 原因: * 解决方式: * 1,使用Vector代替ArrayList,底层是使用synchronized来实现同步的,效率比较低 * 2,使用工具类将其转成安全的:List<String> list = Collections.synchronizedList(new ArrayList<>()); * 3,使用JUC下的CopyOnWriteArrayList:List<String> list = new CopyOnWriteArrayList<>();,使用lock实现同步,效率高 * 它会在写入的时候,避免多线程下同时写入,将其它线程写入的数据覆盖,所以如果该线程想要写入数据时,它只能将数据复制一份出来 * 在复制的数据上面做出修改后,再同步会原来的数据中 */ List<String> list = new CopyOnWriteArrayList<>(); for ( int i= 0 ;i< 20 ;i++) { new Thread(()->{ list.add(UUID.randomUUID().toString().substring( 0 , 5 )); System.out.println(list); },String.valueOf(i)).start(); } } } |
2,对Set进行优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import java.util.*; import java.util.concurrent.CopyOnWriteArraySet; public class JucTest5 { public static void main(String[] args) { /** * hashSet本质上是hashMap,他利用了hashMap中key的不唯一性来实现数据的不重复 * 多线程下hashSet是不安全的,会出现ConcurrentModificationException * 解决方案 * 1,Set<String> set = Collections.synchronizedSet(new HashSet<String>()); * 2,Set<String> set =new CopyOnWriteArraySet<>(); */ //Set<String> set = new HashSet(); //Set<String> set = Collections.synchronizedSet(new HashSet<String>()); Set<String> set = new CopyOnWriteArraySet<>(); for ( int i= 0 ;i< 60 ;i++) { new Thread(()-> { set.add(UUID.randomUUID().toString().substring( 0 , 5 )); System.out.println(set.toString()); },String.valueOf(i)).start(); } } } |
3,对Map进行优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; public class JucTest6 { public static void main(String[] args) { /** * HashMap初始容量为16,扩展因子为0,75 * 多线程下hashMap是不安全的,会出现ConcurrentModificationException * 解决方案 * 1,Map<String,String> map = Collections.synchronizedMap(new HashMap<>()); * 2,Map<String,String> map = new ConcurrentHashMap<>(); */ //Map<String,String> map = new HashMap<>(); //Map<String,String> map = Collections.synchronizedMap(new HashMap<>()); Map<String,String> map = new ConcurrentHashMap<>(); for ( int i= 0 ;i< 60 ;i++) { final int temp = i; //为了线程内可以读取到变量 new Thread(()-> { map.put(UUID.randomUUID().toString().substring( 0 , 5 ),String.valueOf(temp)); System.out.println(map); },String.valueOf(i)).start(); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本