ToB企服应用市场:ToB评测及商务社交产业平台

标题: 常用集合线程安全分析 [打印本页]

作者: 写过一篇    时间: 2023-12-1 14:34
标题: 常用集合线程安全分析
ArrayList在多线程情况下,不安全

具体代码

  1. package com.shaonian.juc.list_thread_secure;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.UUID;
  5. /**
  6. * @author 长名06
  7. * @version 1.0
  8. * 演示ArrayList集合线程不安全
  9. */
  10. public class ListDemo {
  11.     public static void main(String[] args) {
  12.         List<String> list = new ArrayList<>();
  13.         for (int i = 0; i < 10; i++) {
  14.             new Thread(() -> {
  15.                 //会出现java.util.ConcurrentModificationException 并发修改异常
  16.                 list.add(UUID.randomUUID().toString().substring(0, 8));
  17.                 System.out.println(list);
  18.             }, String.valueOf(i)).start();
  19.         }
  20.     }
  21. }
复制代码
解决方案

使用Vector/ConcurrentHashMap集合

  1. package com.shaonian.juc.list_thread_secure;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.UUID;
  5. import java.util.Vector;
  6. /**
  7. * @author 长名06
  8. * @version 1.0
  9. * Vector集合,线程安全 不推荐使用
  10. */
  11. public class VectorDemo {
  12.     public static void main(String[] args) {
  13.         List<String> list = new Vector<>();
  14.         for (int i = 0; i < 30; i++) {
  15.             new Thread(() -> {
  16.                 list.add(UUID.randomUUID().toString().substring(0, 8));
  17.                 System.out.println(list);
  18.             }, String.valueOf(i)).start();
  19.         }
  20.     }
  21. }
复制代码
使用Collections中的synchronizedList()/synchronizedMap()

  1. package com.shaonian.juc.list_thread_secure;
  2. import java.util.*;
  3. /**
  4. * @author 长名06
  5. * @version 1.0
  6. * 使用Collections中的synchronizedList方法,转成对应线程安全的集合,不推荐使用
  7. */
  8. public class CollectionsDemo {
  9.     public static void main(String[] args) {
  10.         List<String> list = Collections.synchronizedList(new ArrayList<>());
  11.         for (int i = 0; i < 30; i++) {
  12.             new Thread(() -> {
  13.                 list.add(UUID.randomUUID().toString().substring(0, 8));
  14.                 System.out.println(list);
  15.             }, String.valueOf(i)).start();
  16.         }
  17.     }
  18. }
复制代码
使用CopyOnwriteArrayList

涉及到写时复制技术,就是说,此集合是可以并发读,但是写操作,同时只能有一个线程执行。写操作时,先将原有的集合内容,copy一份,然后写入新的内容,然后再覆盖原有的集合,覆盖后的集合,就可以读和写了
  1. package com.shaonian.juc.list_thread_secure;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.List;
  5. import java.util.UUID;
  6. import java.util.concurrent.CopyOnWriteArrayList;
  7. /**
  8. * @author 长名06
  9. * @version 1.0
  10. * 使用线程安全的集合如CopyOnWriteArrayList
  11. */
  12. public class CopyOnWriteArrayListDemo {
  13.     public static void main(String[] args) {
  14.         List<String> list = new CopyOnWriteArrayList<>();
  15.         for (int i = 0; i < 30; i++) {
  16.             new Thread(() -> {
  17.                 list.add(UUID.randomUUID().toString().substring(0, 8));
  18.                 System.out.println(list);
  19.             }, String.valueOf(i)).start();
  20.         }
  21.     }
  22. }
复制代码
CopyOnWriteList

CopyOnWriteList相当于线程安全的ArrayList,和ArrayList一样,它是个可变数组,不过有一下特性

HashSet和HashMap在多线程情况下,不安全

  1. package com.shaonian.juc.list_thread_secure;
  2. import java.util.HashSet;
  3. import java.util.List;
  4. import java.util.Set;
  5. import java.util.UUID;
  6. import java.util.concurrent.CopyOnWriteArrayList;
  7. /**
  8. * @author 长名06
  9. * @version 1.0
  10. */
  11. public class HashSetDemo {
  12.     public static void main(String[] args) {
  13.         //解决方案,使用CopyOnWriteHashSet
  14.         Set<String> set = new HashSet<>();
  15.         for (int i = 0; i < 30; i++) {
  16.             //会出现java.util.ConcurrentModificationException
  17.             new Thread(() -> {
  18.                 set.add(UUID.randomUUID().toString().substring(0, 8));
  19.                 System.out.println(set);
  20.             }, String.valueOf(i)).start();
  21.         }
  22.     }
  23. }
复制代码
  1. package com.shaonian.juc.list_thread_secure;
  2. import java.util.*;
  3. /**
  4. * @author 长名06
  5. * @version 1.0
  6. */
  7. public class HashMapDemo {
  8.     public static void main(String[] args) {
  9.         //解决方案,使用ConcurrentHashMap
  10.         Map<String,String> map = new HashMap<>();
  11.         for (int i = 0; i < 30; i++) {
  12.             String key = String.valueOf(i);
  13.             //会出现java.util.ConcurrentModificationException
  14.             new Thread(() -> {
  15.                 map.put(key,UUID.randomUUID().toString().substring(0, 8));
  16.                 System.out.println(map);
  17.             }, String.valueOf(i)).start();
  18.         }
  19.     }
  20. }
复制代码
小结

线程不安全与其对应的安全集合

集合中存在线程存在和线程不安全的例如ArrayList -- Vector HashMap -- HashTable,但是以上都是syncronized关键字实现的。
Collections构建的线程安全集合

通过使用Collections中的synchronizedList()/synchronizedMap(),将不安全的集合,转成线程安全的。
java.util.concurrent包下的

CopyOnWriteList和CopyOnWriteSet类型,通过动态数组与加锁保证线程安全。
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。下·

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4