当前位置:   article > 正文

Java多线程之集合类(线程安全和不安全)_java中所有集合 安全和不安全分类

java中所有集合 安全和不安全分类

Java多线程之集合类(浅析线程安全和不安全)


本文目录:

  • 1.线程不安全之ArrayListHashSetHashMap线程安全CopyOnWriteArrayListCopyOnWriteArraySetConcurrentHashMap
  • 2. 小结
  • 3.解析CopyOnWrite容器

1.线程不安全之ArrayList和线程安全之CopyOnWriteArrayList


测试代码:

  • 多个线程往一个集合中添加内容。
实现:
public static void listNotSafe() {
        List<String> list = new ArrayList<>();
        for (int i = 1; i <= 30 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,6));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

编译结果:
在这里插入图片描述


解决办法:
  • 使用CopyOnWriteArrayList代替ArrayList

使用如下:

public static void listNotSafe() {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 1; i <= 30 ; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,6));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

编译结果:
在这里插入图片描述


小结:

  • 1. 经过测试,发现HashSetHashMap也是线程不安全的,分别对应的解决办法是用CopyOnWriteArraySetConcurrentHashMap替换(如上面的例子)

3.解析CopyOnWrite容器

  • 我们发现CopyOnWrite容器能够解决线程不安全的问题,现在来通过源码进行解析(以CopyOnWriteArrayList)为例。

源码部分如下
在这里插入图片描述


其中的add(E e)方法
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();
		    }
		}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

可以知道:
  1. 都是有线程锁的,所以是线程安全的
  2. CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[ ]添加,而是先将当前容器Object[ ]进行Copy,复制出一个新的容器Object[] newElements,然后往新的容器Object[ ] newElements里添加元素,添加完元素之后,再将原容器的引用指向新的容器 setArray(newElements)。
  3. 好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器

扩展小知识:
  1. HashSet底层是HashMap
    在这里插入图片描述

  1. 你可能会想,HashSet是一个参数,而HashMap是键值对存在的。那是因为HashSet只用了HashMap是键,它的值是一个固定的Object对象。
    在这里插入图片描述
    在这里插入图片描述
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/670910
推荐阅读
相关标签
  

闽ICP备14008679号