并发编程之的ArrayList安全性的详细解析

简介: 并发编程之的ArrayList安全性的详细解析

ArrayList不安全

ArrayList中的add方法没有synchronized修饰,是不安全的

下面代码运行结果(异常 java.util.ConcurrentModificationException):



import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
 * @author zkw
 * @Description list不安全
 */
public class ThreadList {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            }, i+"").start();
        }
    }
}
解决方法
  1. 使用Vector (已过时) 使用的是synchronized机制
  2. 使用Collections.synchronizedList()方法修饰ArrayList (性能不高)
    Collections中还有synchronizedMap和synchronizedSet的方法,可以修饰线程不安全的HashSet,HashMap
  3. 使用java.util.concurrent.CopyOnWriteArrayList(推荐)使用的是lock锁

使用CopyOnWriteArrayList

底层使用的是ReentrantLock可重用锁

下面给出CopyOnWriteArrayList 的 add源码

 

 final transient ReentrantLock lock = new ReentrantLock();    
    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    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();
        }
    }

案例运行结果:

案例源码:



import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
/**
 * @author zkw
 * @Description list不安全
 */
public class ThreadList {
    public static void main(String[] args) {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 30; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            }, i+"").start();
        }
    }
}

CopyOnWriteArrayList解析

CopyOnWriteArrayList 利用的是读写分离的思想,读和写的是不同的容器

底层使用的是一个Object数组,每次新添加元素的时候利用的是Arrays.copyOf来创建一个新数组达到扩容效果

使用的是ReentrantLock来保证线程安全

写时复制 Copyonwrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容涨object[]添加,而是先将当前容器 object[ ]进行copy,复制出一个新的容器object[ ] newELements,然后新的容器object[ ] newELements里添加元素,添加 完元素之后, 再将原容器的引用指向新的容器setArray(newELements);。这样做的好处是可以对Copyonwrite容器进行并发的读,而不需 要加锁,因为当前容器不会添加任何元素。所以Copyonwdrite容器也是一种读写分离的思想,读和写不同的容器。

 

 final transient ReentrantLock lock = new ReentrantLock();  
    private transient volatile Object[] array;
    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    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); //将新容器设置为该list的容器
            return true;
        } finally {
            lock.unlock();
        }
    }


相关文章
|
7天前
|
人工智能 Go 调度
掌握Go并发:Go语言并发编程深度解析
掌握Go并发:Go语言并发编程深度解析
|
7天前
|
Java
并发编程之线程池的应用以及一些小细节的详细解析
并发编程之线程池的应用以及一些小细节的详细解析
17 0
|
7天前
|
Rust 安全 程序员
使用Rust进行系统编程:安全性优势深度解析
【5月更文挑战第14天】Rust,Mozilla开发的系统编程语言,以其内存安全、并发支持和静态类型系统在系统编程中脱颖而出。所有权和借用检查机制消除内存错误,无锁并发原语提升安全性,静态类型减少运行时错误,最小权限原则降低权限风险。强大的社区支持和安全审计进一步确保了代码的安全性和稳定性,使Rust成为安全高效系统编程的理想选择。
|
7天前
|
算法 Java Go
ArrayList源码解析
ArrayList源码解析
13 1
|
7天前
|
并行计算 数据处理 开发者
Python并发编程:解析异步IO与多线程
本文探讨了Python中的并发编程技术,着重比较了异步IO和多线程两种常见的并发模型。通过详细分析它们的特点、优劣势以及适用场景,帮助读者更好地理解并选择适合自己项目需求的并发编程方式。
|
7天前
|
存储 安全
【并发编程】深入解析CurrentHashmap
【并发编程】深入解析CurrentHashmap
6 0
|
7天前
|
存储 安全 Java
Java并发编程中的高效数据结构:ConcurrentHashMap解析
【4月更文挑战第25天】在多线程环境下,高效的数据访问和管理是至关重要的。Java提供了多种并发集合来处理这种情境,其中ConcurrentHashMap是最广泛使用的一个。本文将深入分析ConcurrentHashMap的内部工作原理、性能特点以及它如何在保证线程安全的同时提供高并发性,最后将展示其在实际开发中的应用示例。
|
7天前
|
存储 安全 Java
Java集合篇之深入解析ArrayList,这六问你答的上来吗?
Java集合篇之深入解析ArrayList,这六问你答的上来吗?
15 1
|
5天前
|
Linux 网络安全 Windows
网络安全笔记-day8,DHCP部署_dhcp搭建部署,源码解析
网络安全笔记-day8,DHCP部署_dhcp搭建部署,源码解析
|
6天前
HuggingFace Tranformers 源码解析(4)
HuggingFace Tranformers 源码解析
6 0

推荐镜像

更多