A coleção JAVA de alta simultaneidade (JUC) não é segura

O primeiro é nosso ArrayList:

Desta vez, explicamos a insegurança das coleções, em primeiro lugar, todos nós conhecemos o ArrayList!
Em primeiro lugar, expandimos alguns pontos de conhecimento. A camada inferior de ArrayList é uma matriz do tipo Object. A capacidade inicial é 10 (antes de jdk7, depois de jdk8 ser uma referência nula, ela se tornará 10 após adicionar, semelhante ao mecanismo de carregamento lento), e seu método de expansão Cada expansão é metade da anterior. Por exemplo, 10 será expandido para 15 e 15 será expandido para 22. O método usado para expansão é o método copyof de Arrays. OK, então entre no tópico.
Olhe para este código primeiro:

List<String> list=new ArrayList<>();

Então, usamos expressões Lambda para gerar vários threads

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

Uma exceção será relatada posteriormente:
java.util.ConcurrentModificationException
Causa da
exceção de modificação simultânea : Competição de simultaneidade multi-threaded para recursos uniformes e nenhum bloqueio. Então, quais soluções temos ? ?
método um:

 List<String> list = new Vector<>();

Coleção de vetores, a camada inferior adiciona synchronized (relocking) ao método add. Há apenas um thread ao mesmo tempo, o que é ineficiente, então é por isso que a coleção é ineficiente e segura.

Método dois:

Collections.synchronizedList(new ArrayList<>());

Este é um método estático de Connections, passando em um ArrayList.

Método três:

List<String> list = new CopyOnWriteArrayList<>();

A classe deste pacote JUC implementa a interface List.
Camada inferior: array Object [] volátil
tem um bloqueio ReentrantLock em seu método 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();
        }
    }

**

Em seguida, olhamos para a coleção Set:

Os mesmos pontos de conhecimento estendido, a estrutura de dados subjacente de HashSet é HashMap (new HashMap () no construtor de código-fonte) e seu método add realmente retorna map.put (e, PRESENT ) == null; PRESENT é na verdade um objeto sempre ativo , Portanto, são realmente as chaves do HashMap.
As mesmas etapas:

        Set<String> set=new HashSet<>();
        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();
        }

O mesmo é um erro:
java.util.ConcurrentModificationException
Solução:
Método 1:

Set<String> set=Collections.synchronizedSet(new HashSet<>());

Método dois:

 Set<String> set=new CopyOnWriteArraySet();

Também é uma classe em JUC e seu construtor é, na verdade, new CopyOnWriteArrayList ();

Então é o nosso Mapa:

Conhecimento estendido: a camada inferior do HashMap (não ordenado e sem repetição) é matriz + lista vinculada (unidirecional) + árvore vermelha e preta, o HashMap armazena o nó e o nó armazena o valor-chave. A capacidade inicial do HashMap é 16 e o ​​fator de carga é 0,75 ( Expanda a capacidade quando atingir 16 * 0,75), a capacidade inicial e o fator de carga podem ser alterados através do construtor, e a capacidade original será duplicada a cada vez.

 Map<String, String> map = new HashMap<>();
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
                System.out.println(map);
            }, String.valueOf(i)).start();
        }

O mesmo erro será relatado: solução
java.util.ConcurrentModificationException
:

 Map<String, String> map = new ConcurrentHashMap();

Sob o pacote JUC.

Desta vez, o acervo do JUC explicou que esse momento não é seguro. Espero que possa te ajudar. Se você tiver sugestões melhores, deixe seu recado!

Acho que você gosta

Origin blog.csdn.net/Pzzzz_wwy/article/details/105960684
Recomendado
Clasificación