zoukankan      html  css  js  c++  java
  • 基础巩固篇 —— 对不安全集合的理解

    一、不安全集合类

    说到不安全的集合类,一般会想到ArrayList,HashSet,HashMap,这三种最常用的。

    二、ArrayList类的不安全性

    不安全原因

    ArrayList的底层是数组,new ArrayList()是定义一个空数组{},当添加数据的时候进行扩容,初次扩容容量默认为10,通过Arrays.copyOf(elementData, newCapacity)进行数组复制,实现扩容。为了满足高并发需求,并没有对ArrayList内的方法进行同步实现,这样就会出现多个线程同时进行数组复制操作,然后数据复制异常(ConcurrentModificationException)

    解决方案

    1. 使用ArrayList的安全类Vector,Vector中的方法都是被synchronized关键字修饰的,每次调用添加方法只允许一个线程进行操作,保证了线程安全,降低并发量
    2. 使用Collectoins工具类的同步包装方法
    List<String> list = Collections.synchronizedList(new ArrayList<>());
    
    1. 使用java.util.concurrent包下的CopyOnWriteArrayList类
    • 代码:
    List<String> list = new CopyOnWriteArrayList<>();
    // 添加方法的源码
    public boolean add(E e) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len + 1);
                newElements[len] = e;
                setArray(newElements);
                return true;
            } finally {
                lock.unlock();
            }
        }
    
    • 原理:在进行add方法时添加了ReentrantLock非公平锁,这样就可以保证只能由一个线程进行写操作

    二、HashSet类的不安全性

    不安全原因

    HashSet的底层是HashMap,new HashSet()是new HashMap(),当添加数据的时候,添加的数据作为map的key,value为固定值PRESENT = new Object()。高并发情况下,进行抢占式写入操作时也会造成并发更新数据异常(ConcurrentModificationException)

    解决方案

    1. 使用Collectoins工具类的同步包装方法
    Set<String> set = Collections.synchronizedSet(new HashSet<>());
    
    1. 使用java.util.concurrent包下的CopyOnWriteArraySet类
    • 代码:
    Set<String> set = new CopyOnWriteArraySet<>();
    // 底层调用还是CopyOnWriteArraySet
    public CopyOnWriteArraySet() {
            al = new CopyOnWriteArrayList<E>();
        }
    

    三、HashMap类的不安全性

    不安全原因

    HashMap的底层是数组+链表结构。高并发情况下,进行抢占式写入操作时也会造成并发更新数据异常(ConcurrentModificationException)

    解决方案

    1. 使用Collectoins工具类的同步包装方法
    Map<String, Object> map = Collections.synchronizedMap(new HashMap<>());
    
    1. 使用java.util.concurrent包下的ConcurrentHashMap类,它实现了ConcurrentMap接口
    • 代码:
    Map<String, Object> map = new ConcurrentHashMap<>();
    
  • 相关阅读:
    System.Net.Http.HttpClient POST 未能创建 SSL/TLS 安全通道
    SQL Server用户权限查询
    IIS 7 Deploy .Net Framework 4.8 Application
    System.Net.Http.HttpClient 模拟登录并抓取弹窗数据
    HtmlAgilityPack Sample
    嵌套 struct & class 的遍历
    SQL循环插入测试数据
    windows文本转语音 通过java 调用python 生成exe可执行文件一条龙
    Centos8 删除了yum.repos.d 下面的文件
    nacos 配置
  • 原文地址:https://www.cnblogs.com/zzb-yp/p/15034893.html
Copyright © 2011-2022 走看看