• 集合不安全之 ---> 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();
            }
        }
  • 相关阅读:
    SHAREPOINT2007 文档库中通过EMAIL发送文档URL为乱码的解决方法
    ReadTrace
    实战分区表:SQL Server 2k5&2k8系列
    mssql 如何创建跟踪
    SQL Server自定义异常的使用raiserror
    SQL Server 2008内存及I/O性能监控
    实战 SQL Server 2008 数据库误删除数据的恢复
    MSSQL常用性能測試語句
    sqlserver 2008 设置了镜像 如何收缩日志文件
    复制订阅错误处理。
  • 原文地址:https://www.cnblogs.com/cb1186512739/p/12736255.html
Copyright © 2020-2023  润新知