• 线程不安全(Arraylist,HashSet,HashMap)和写时复制


    package com.yangyuanyuan.juc1205;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.UUID;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.CopyOnWriteArrayList;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    /**
     *
     * 1 故障现象
     *  java.util.ConcurrentModificationException
     *
     * 2 导致原因
     *
     * 3 解决方法
     *   3.1 new Vector<>()
     *   3.2 Collections.synchronizedList(new ArrayList<>());
     *   3.3 new CopyOnWriteArrayList()
     *
     *
     * 4 优化建议(同样的错误不犯第2次)
    
     *
     */
    public class NotSafeDemo03
    {
        public static void main(String[] args)
        {
            Map<String,String> map = new ConcurrentHashMap<>();
            for (int i = 1; i <=30; i++)
            {
                new Thread(() -> {
                    map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
                    System.out.println(map);
                },String.valueOf(i)).start();
            }
        }
    
        public static void setNotSafe()
        {
            Set<String> set = new CopyOnWriteArraySet<>();
            for (int i = 1; i <=30; i++)
            {
                new Thread(() -> {
                    set.add(UUID.randomUUID().toString().substring(0,8));
                    System.out.println(set);
                },String.valueOf(i)).start();
            }
        }
    
        public static void listNotSafe()
        {
            List<String> list = new CopyOnWriteArrayList();//Collections.synchronizedList(new ArrayList<>());//new Vector<>();//new ArrayList<>();
    
            for (int i = 1; i <=30; i++)
            {
                new Thread(() -> {
                    list.add(UUID.randomUUID().toString().substring(0,8));
                    System.out.println(list);
                },String.valueOf(i)).start();
            }
        }
    }
    
    
    
    
    /**笔记
     * 写时复制
     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[] elements = getArray();
                 int len = elements.length;
                 Object[] newElements = Arrays.copyOf(elements, len + 1);
                 newElements[len] = e;
                 setArray(newElements);
                 return true;
             }
             finally {
                lock.unlock();
         }
     }
     */
  • 相关阅读:
    proxool数据库连接池用法
    SQL Server 用链接server 同步MySQL
    使用DNSCrypt解决Dropbox污染问题
    POJ 1952 BUY LOW, BUY LOWER DP记录数据
    使用doxygen为C/C++程序生成中文文档
    构造器(二)----指定构造器、便利构造器
    Spring Boot 部署与服务配置
    排序算法c语言描述---冒泡排序
    【转】Android Studio系列教程一--下载与安装
    【转】Windows环境下Android Studio v1.0安装教程
  • 原文地址:https://www.cnblogs.com/qfdy123/p/14324279.html
Copyright © 2020-2023  润新知