天天看点

JUC详解-5-集合类不安全

JUC详解 -> 集合类不安全

1. CopyOnWriteArrayList

  • 并发下 ArrayList不安全
  • ConcurrentModificationException
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

//ConcurrentModificationException 并发修改异常!
public class ListTest {
    public static void main(String[] args) {
        //并发下ArrayList 不安全
        /**
         * 解决方案:
         * 1.List<String> list = new Vector<>();
         * 2.List<String> list = Collections.synchronizedList(new ArrayList<String>());
         * 3.List<String> list = new CopyOnWriteArrayList<>();
         *   CopyOnWrite 写入时复制  简称COW  计算机程序设计领域的一种优化策略
         *   当多个线程调用的时候,读取(list)时是固定的,写入可能会造成覆盖,
         *   CopyOnWrite在写入的时候避免覆盖造成数据问题!
         *   读写分离的思想
         */
        /**
         * CopyOnWriteArrayList & Vector:
         *   CopyOnWriteArrayList add()使用lock锁; Vector:Synchronized
         *   CopyOnWriteArrayList效率更高!
        
         */
        //List<String> list = 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();
        }
    }
}
           
  • CopyOnWriteArrayList & Vector:
    • CopyOnWriteArrayList中add():
      JUC详解-5-集合类不安全
    • Vector中addElement():
      JUC详解-5-集合类不安全

2. CopyOnWriteArraySet

import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * ConcurrentModificationException !并发修改异常!
 *解决方案:
 * 1.Set<String> set = Collections.synchronizedSet(new HashSet<String>());
 * 2.Set<String> set = new CopyOnWriteArraySet<String>();
 */
public class SetTest {
    public static void main(String[] args) {
        //Set<String> set = new HashSet<String>();
        //Set<String> set = Collections.synchronizedSet(new HashSet<String>());
        Set<String> set = new CopyOnWriteArraySet<>();

        for (int i = 1; i <= 30; i++) {
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(set);
            },String.valueOf(i)).start();
        }
    }
}
           
  • HashSet的底层是什么?
    JUC详解-5-集合类不安全
    • HashSet中的add():
      JUC详解-5-集合类不安全
    • set的本质就是map的key,key是无法重复的

3. ConcurrentHashMap

  • map是这么用的吗? 不是!工作中不用HashMap
  • 默认等价于什么? 加载因子0.75 初始化容量16
    JUC详解-5-集合类不安全
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
//ConcurrentModificationException !并发修改异常

public class MapTest {
    public static void main(String[] args) {
        /**
         * 回顾Map
         * map是这么用的吗? 不是!工作中不用HashMap
         * 默认等价于什么? 加载因子0.75  初始化容量16
         */
        
        /**
         * 解决方案:
         * 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 = 1; i <= 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
                System.out.println(map);
            },String.valueOf(i)).start();
        }
    }
}
           
  • ConcurrentHashMap的原理?