[06002] JUC how to thread safe collection classes replaced with thread-safe class? The main copy (CopyOnWrite) write involved

A series of problems caused by the ArrayList

EDITORIAL: Be sure to firmly remember java.util.ConcurrentModificationException, CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap

  1. new ArrayList () new underlying what? Array
  2. What types of underlying? Object think list.add can pretend consequently can hold
  3. Java8 an example to the initial value is how much? Start after empty add 10
  4. Deposit 25 elements can do? Yes, the underlying expansion, how to expand the 10 "15, spread half the original value
  5. You have not read the source code, how to move in? Arrays.copyOf ()
  6. The second expansion to expand the number? 22 hashmap expansion is twice the original value of 16 "32
  7. 7.ArrayList thread-safe or unsafe? Unsafe
  8. For example thread unsafe code?
  9. Vector is thread-safe, why has it ArrayList? Concurrency and consistency is itself at odds, not much before concurrency, lock table, only one thread operation
  10. Thread unsafe how to solve?
  11. Why copy the security write?
package com.magic.juc0117;

/**
 * @Description
 * @Author Chelsea
 * @Date 2020/1/17 17:18
 */
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;

/**
 * 1.故障现象
 * java.util.ConcurrentModificationException
 * 2.导致原因
 * 多线程并发争抢同一个资源类并且没有加锁
 * 3.解决方法
 * ① List<String> list = new Vector<>();//源码加锁synchronized(重锁)
 * 根据效率和安全性选择,电商ArrayList不多
 * 不许用vector,请用②解决
 * ②List<String> list = Collections.synchronizedList(new ArrayList<>());
 * 如果②也不让用
 * ③List<String> list = new CopyOnWriteArrayList();//写时复制
 *
 * 4.优化建议(同样的错误不能犯2次)
 */

/**
 * 一个常问的题目:Collection 和 Collections有什么区别?
 * Collection 接口 Collections集合接口的工具类
 */
public class NotSafeDemo03 {

    public static void main(String[] args) {
        listNotSafe();
//同理HashSet、HashMap也是线程不安全的,JUC也提供了对应的安全的类
//        Set<String> set = new HashSet<>();
        Set<String>  set = new CopyOnWriteArraySet<>();
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(set);
            },String.valueOf(i)).start();

        }
//HashMap   ConcurrentHashMap

    }

    public static void listNotSafe(){
//        List<String> list = new ArrayList();
//        list.add("a");
//        list.add("a");
//        list.add("a");
//        list.forEach(System.out::println);  这样不会不安全只有一个线程,下面for循环会异常ConcurrentModificationException
// 换成下面三种方式时异常解决
//        List<String> list = new Vector<>();//源码加锁synchronized
//        List<String> list = Collections.synchronizedList(new ArrayList<>());
        List<String> list = new CopyOnWriteArrayList();//写时复制


        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();

        }
    }


    /**
     * 1.HashSet底层数据结构  HashMap  也不安全
     * 选择CopyOnWriteArraySet
     */

    /**
     *  HashMap
     *  ConcurrentHashMap
     */
}

To answer questions the very beginning, why copy the security write?
Below is the source CopyOnWriteArrayList class add () method, the source code can be known lock, the concurrent lock reentrant and efficiency is greatly improved.

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();
    }
}

Learn finishing in JUC .

Published 53 original articles · won praise 0 · Views 374

Guess you like

Origin blog.csdn.net/weixin_40778497/article/details/104038990