[06002] JUCスレッドセーフなクラスに置き換え安全なコレクションクラスをスレッドにどのように?関与メインコピー(コピーオンライト)のライト

ArrayListに起因する一連の問題

EDITORIAL:CopyOnWriteArrayListと、CopyOnWriteArraySet、のConcurrentHashMap、しっかりjava.util.ConcurrentModificationExceptionがを忘れないようにしてください

  1. 新しいArrayListを()新しい何か根本的な?配列
  2. 基礎となるのはどのような種類?オブジェクトが保持することができ、結果としてふりをすることができlist.add考えます
  3. 初期値にJava8例はどのくらいですか?空のアドオン10の後にスタート
  4. デポジット25の要素が行うことができますか?はい、10「15を拡大するための方法を根本的な拡大は、半分の元の値を広めます
  5. あなたがソースコードを読んでいない、どのように移動するには?Arrays.copyOf()
  6. 数を拡大するための第2膨張?22ハッシュマップの拡張は「32 16の倍元の値であります
  7. 7.ArrayListスレッドセーフまたは安全ではありませんか?安全でありません
  8. たとえば、危険なコードをスレッド?
  9. ベクターは、なぜそれをArrayListを持っている、スレッドセーフですか?同時実行性と一貫性がなく、多くの同時実行、ロックテーブル、一つだけのスレッド操作の前に、オッズで自分自身であります
  10. 解決するためにどのように危険なスレッド?
  11. なぜセキュリティの書き込みをコピー?
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
     */
}

回答の質問は非常に先頭に、なぜセキュリティの書き込みをコピー?
以下、ソースコードがロックを知ることができるソースCopyOnWriteArrayListとクラスadd()メソッドであり、同時ロックリエントラントと効率が大幅に向上します。

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

仕上げ学びJUC

公開された53元の記事 ウォンの賞賛0 ビュー374

おすすめ

転載: blog.csdn.net/weixin_40778497/article/details/104038990