欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JUC之集合

程序员文章站 2022-04-17 21:37:18
...

常见的有哪些是线程不安全的?

1、集合类是不安全的:ArrayList,HashSet,HashMap等等都是不安全

2、i++, ++i 也是不安全

JUC什么?

1、juc是java.util.concurrent包的简称,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的Collection 实现等

2、高并发最容易出现的异常是:

ConcurrentModificationException

3、高并发的项目不能使用ArraryList,只能使用juc报下的集合


 * 1    lambda Express
 *  1.1 如何写:    拷贝形括号,写死右箭头,落地大括号
 *  1.2 Lamdba 有且仅有一个方法,注解@FunctionalInterface
 *  1.3 default
 *  1.4 静态方法

一、题目:请举例说明集合类是不安全的-----面试题

 List<String> list = new ArrayList<String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(1,4));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

运行该代码会报:ConcurrentModificationException异常

为什么会出现这种情况?1.5版本之前是使用的线程安全,但是为了效率改成了不安全的,详情见https://blog.csdn.net/u012859681/article/details/78206494

二、使用JUC解决

原理:写时复制,这个类似于mysql的读写分离

 CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy, 复制出一个新的容器Object[] newElements,然后新的容器Object[] newElements里添加元素,添加完元素之后,
     再将原容器的引用指向新的容器 setArray(newElements);。这样做的好处是可以对CopyOnWrite容器进行并发的读,
     而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器
     public boolean add(E e) {
     final ReentrantLock lock = this.lock;
     lock.lock();
     try {
     Object[] ele ments = getArray();
     int len = elements.length;
     Object[] newElements = Arrays.copyOf(elements, len + 1);
     newElements[len] = e;
     setArray(newElements);
     return true;
     } finally {
     lock.unlock();
        }
     }

实现代码:

list----CopyOnWriteArrayList

set----CopyOnWriteArraySet

map---ConcurrentHashMap

List<String> list = new CopyOnWriteArrayList<String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(1,4));
                System.out.println(list);
            },String.valueOf(i)).start();
        }

 Set<String> set = new CopyOnWriteArraySet<String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(1,4));
                System.out.println(set);
            },String.valueOf(i)).start();
        }

 Map<String,String> map = new ConcurrentHashMap<String,String>();

        for (int i = 1; i <=30; i++)
        {
            new Thread(() -> {
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(1,4));
                System.out.println(map);
            },String.valueOf(i)).start();

        }

 

 

相关标签: JUC