• 线程不安全(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();
         }
     }
     */
  • 相关阅读:
    UVA 12657 Boxes in a Line 双向链表模拟
    C语言单片和C#语言服务器端DES及3DES加密的实现
    关于TcpClient,Socket连接超时的几种处理方法
    拿来参考的学习计划
    faire la course
    今日法语2
    炸鱼
    今日法语
    今日疑问
    下周想做的菜
  • 原文地址:https://www.cnblogs.com/qfdy123/p/14324279.html
Copyright © 2020-2023  润新知