zoukankan      html  css  js  c++  java
  • 集合不安全之 ---> List

    List : 在多线程操作List的时候,在一个线程里面add东西,list实际上的大小跟预计是不一样的

      public void demo1() {
            List<String> list = new ArrayList<>();
            Random random = new Random();
    
            for (int i = 0; i < 10; i++) {
                new Thread(()->{
                    list.add(String.valueOf(random.nextInt()));
                    System.out.println(list);
                }).start();
            }
    
            //出现异常:Exception in thread "Thread-0" java.util.ConcurrentModificationException
        }

    解决方法:

    • - 使用Vector类,Vector线程安全,缺点效率不高。
    • - 使用Collections.synchronizedList()方法,参数为一个List对象
    • - 使用CopyOnWriteArrayList类

    CopyOnWriteArrayList的底层 add() 方法的实现:

    原理:写时进行复制

    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();//返回object数组
            int len = elements.length; //得到原数组的长度
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;//进行下标赋值
            setArray(newElements);//进行数组赋值
            return true;
        } finally {
            lock.unlock();
        }
    }


    //setArray的源码

    final void setArray(Object[] a) {
        array = a;
    }
     

    remove方法:

        public E remove(int index) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                Object[] elements = getArray();
                int len = elements.length;
                E oldValue = get(elements, index);
                int numMoved = len - index - 1;  //得到数组的整体之后的长度
                if (numMoved == 0)
                    setArray(Arrays.copyOf(elements, len - 1));
                else {
                    Object[] newElements = new Object[len - 1];
                    System.arraycopy(elements, 0, newElements, 0, index);
                    System.arraycopy(elements, index + 1, newElements, index,
                                     numMoved);
                    setArray(newElements);
                }
                return oldValue;
            } finally {
                lock.unlock();
            }
        }
  • 相关阅读:
    终于成功发布我的博客园处女贴,不过,真的颇费周章,两个htmleditor都非常不好用~~
    全文本代码着色(带源码和示例)
    BlogBench Ver 1.0 发布
    [在windows上使用Unix工具]cygwin
    Linux下压缩与解压
    Linux设置界面或命令行启动
    perl模块安装
    Linux下patch的制作和应用
    TAR命令参数详解
    在windows上使用Sysinternals工具
  • 原文地址:https://www.cnblogs.com/cb1186512739/p/12736255.html
Copyright © 2011-2022 走看看