• 集合之Map和List线程安全问题


    一、Map常见的子类有:

    1、HashMap:
              底层数据结构是哈希表,线程不安全,允许null键和null值
    
    2、Hashtable:
              线程安全的,不允许null键和null值,效率低,给整个方法添加synchronized,太笨重
    
    3、LinkedHashMap:
              底层数据结构是链表和哈希表,由链表保证有序(存储和取出的顺序一致),哈希表保证唯一,线程不安全
    
    4、TreeMap:
              底层数据结构是红黑树(一种自平衡的二叉树),可以按照某种规则进行排序,自然排序和选择器排序,线程不安全
    
    5、ConcurrentHashMap:
            ● 线程安全的,不允许null键和null值
    
            ● 对与多线程的操作,介于HashMap与Hashtable之间。
    
            ● 内部采用"锁分段"机制代替Hashtable的独占锁。进而提高性能。
    
           【查看源码:Hashtable是给整个方法上面添加synchronized,而ConcurrentHashMap是给可能出现线程安全问题的代码用同步代码块的方式加锁】
    
            ● 获取操作(包括 get)通常不会受阻塞
    

    默认初始容量是16
    加载因子是0.75,即当 元素个数 超过 容量长度的0.75倍 (即16*0.75=12)时,进行扩容

    线程安全的LIST

    List<Integer> vector = new Vector<>();
    List<Integer> listSyn = Collections.synchronizedList(new ArrayList<>());
    List<Integer> copyList = new CopyOnWriteArrayList<>();
    

      

    ArrayList线程不安全:主要是多线程在写入数据时,会有重复写入的问题

    Vector线程安全:主要是在添加元素的时候,加上了synchronized

    public synchronized E set(int index, E element) {
    if (index >= elementCount)
    throw new ArrayIndexOutOfBoundsException(index);
    
    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
    }


    Collections.synchronizedList:主要是一个大的集合框架里面也是synchronized

    public boolean add(E e) {
    synchronized (mutex) {return c.add(e);}
    }
    CopyOnWriteArrayList:主要是使用ReentrantLock,每次添加元素都会复制旧的数据到新的数组里面,同时使用锁
    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();
    }
    }


    总结
    ArrayList 单线程中使用

    多线程中,并发在2000以内的使用Collections.synchronizedList;并发在2000以上的使用CopyOnWriteArrayList;Vector是JDK1.1版本就有的集合是一个重量级的,不建议使用。

  • 相关阅读:
    关于mysql创建数据库中字符集和排序规则的选择
    关于springboot中数据库连接池报错:testWhileIdle is true, validationQuery not set
    微软不允许以maven的方式直接下载该文件 (com.microsoft.sqlserver:sqljdbc4:jar:4.0),记录一下解决方案
    关于 idea 添加 web项目非 maven
    关于 tomcat版本和jdk版本的问题
    关于 jquery中的 只读两种属性(readonly,disabled),
    layui中如何给 表单中的input标签动态赋值,怎么获取父页面中的值
    pl/sql developer F5快捷键
    SQL中的left outer join,inner join,right outer join用法
    Aix下使用rman备份Oracle RAC数据库
  • 原文地址:https://www.cnblogs.com/zhangliang88/p/16644246.html
Copyright © 2020-2023  润新知