唐僧喜欢小龙女

导航

CopyOnWriteArrayList 的学习

1、为什么要有CopyOnWriteArrayList

原因是ArrayList 在多线程的情况下 会有线程不安全的问题

/**
 *  一、list 在多线程下是不安全的 会报 如下的异常,出现的情况是 当前的容器列表既有读又有写,如果只是写或者读不会报如下的异常。
 *  java.util.ConcurrentModificationException 这个叫并发修改异常
 *  二、解决办法
 *      1、List list = new Vector();这个是线程安全的
 *      2、List list = Collections.synchronizedList(new ArrayList<>());
 *      3、List list = new CopyOnWriteArrayList();  叫写入时复制 简称cow,
 *  三、CopyOnWriteArrayList的原理
 *      就是写的时候先复制一份数据,在新的数据上写,写好了指针指向新的数据。就是读写分离的一个思想。
 *  四、CopyOnWriteArrayList 的优点缺点
 *      优点:
 *          读操作性能很高,因为无需任何同步措施,比较适用于读多写少的并发场景。Java的list在遍历时,
 *          若中途有别的线程对list容器进行修改,则会抛出ConcurrentModificationException异常。
 *          而CopyOnWriteArrayList由于其"读写分离"的思想,遍历和修改操作分别作用在不同的list容器,
 *          所以在使用迭代器进行遍历时候,也就不会抛出ConcurrentModificationException异常了
 *
 *      缺点:
 *          缺点也很明显,一是内存占用问题,毕竟每次执行写操作都要将原容器拷贝一份,数据量大时,对内存压力较大,
 *          可能会引起频繁GC;二是无法保证实时性,Vector对于读写操作均加锁同步,可以保证读和写的强一致性。
 *          而CopyOnWriteArrayList由于其实现策略的原因,写和读分别作用在新老不同容器上,
 *          在写操作执行过程中,读不会阻塞但读取到的却是老容器的数据。
 *
 *
 *
 */
public class CopyOnWriteArrayListDemo {

    public static void main(String[] args) {


        //判断当前机器最大的处理器数 就是看看是几核的cpu
        System.out.println(Runtime.getRuntime().availableProcessors());
        int num = Runtime.getRuntime().availableProcessors();
        ThreadPoolExecutor excutors = new ThreadPoolExecutor(
                8,
                num,
                1000,  //超时等待的时间,就是345 中的窗口 这段时间没有人办理业务就要关闭,释放线程了。
                TimeUnit.SECONDS,
                new LinkedBlockingQueue(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());//其中的一个拒绝策略,


        //List list = new LinkedList();
        //List list = new Vector();
        //List list = Collections.synchronizedList(new ArrayList<>());
        List list = new CopyOnWriteArrayList();
        try{
            for (int i = 0; i < 94; i++) {
                excutors.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"======ok");
                    list.add(UUID.randomUUID().toString().substring(0,5));
                    System.out.println(list);
                });

            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            excutors.shutdown();
        }

    }


}

  

posted on 2021-09-25 21:40  与时具进&不忘初心  阅读(34)  评论(0编辑  收藏  举报