Compreenda CAS e AQS em um artigo

JAVA multithreading, algo que os entrevistadores gostam de perguntar

Algumas coisas conceituais

Atomicidade significa que a operação é indivisível. Independentemente de ser multi-core ou single-core, uma quantidade atômica, apenas um thread pode operar nela por vez. Resumindo, as operações que não são interrompidas pelo planejador de thread durante toda a operação podem ser consideradas atômicas. Por exemplo, a = 1;

Não atomicidade: isso significa que o escalonador de thread interromperá a operação durante todo o processo. Operações
como "a ++" não são atômicas, pois podem ter que passar pelas duas etapas a seguir:

(1) Pegue o valor de um

(2) Calcule a + 1

Se houver dois threads t1, t2 está executando tais operações. Após a primeira etapa, t1 foi interrompido pelo escalonador de thread antes que tivesse tempo de adicionar 1, então t2 começou a executar. Depois que t2 foi executado, t1 começou a executar a segunda etapa (neste momento, o valor de a em t1 pode ainda seja o valor antigo, não é certo, ele só aparecerá se o valor de a na thread t2 não for atualizado para t1 no tempo). Ocorreu um erro neste momento, e a operação de t2 é equivalente a ser ignorada

Agendamento de thread JAVA - agendamento preemptivo (prioridade)


CAS— (compare e troque) compare e troque

Adote o pensamento de bloqueio otimista - sempre pense que você pode concluir a operação

Quando vários encadeamentos manipulam uma variável, apenas um encadeamento será atualizado com sucesso, os outros falham e o encadeamento com falha pode tentar novamente

Rotação CAS esperando

Bloqueia ou synchronizedpode ser alcançado operação atômica de palavra-chave, então por que usar CAS, porque o bloqueio ou desempenho de palavra-chave sincronizada trouxe grande perda, mas com o bloqueio otimista de CAS pode ser alcançado, é na verdade o uso direto das instruções de nível de CPU, então o desempenho é muito alto.

Então, como o CAS realiza o bloqueio de rotação? O CAS usa instruções da CPU para garantir a atomicidade da operação para obter o efeito de bloqueio. Quanto ao spin, geralmente é realizado com um loop infinito. Desse modo, em um loop infinito, é executada uma operação CAS. Quando a operação é bem-sucedida e retorna verdadeiro, o loop termina; quando retorna falso, o loop continua e a operação CAS continua a ser tentada até retornar verdadeiro.

Insira o código-fonte do CAS para ver
import java.util.concurrent.atomic.AtomicInteger;

Defina atomicamente o valor para o valor atualizado fornecido ( update), se o valor atual for igual ao valor esperado ( expect). Retorna verdadeiro, atualiza o valor da variável, o valor real não é igual ao valor esperado, retorna falso, a thread não faz nada, CAS retorna o valor da variável atual;

public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

Dentro unsafe.compareAndSwapInt(this, valueOffset, expect, update);dele está um nativemétodo, usando a implementação c ++, se estiver interessado pode ir e ver os arquivos de código-fonte JDK safe.cpp, o CAS opera diretamente com o sistema operacional;

public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
Problema ABA causado por CAS

O que é ABA?

Posso saber do exposto que existe uma premissa importante para a implementação do algoritmo CAS: você precisa retirar os dados em um determinado momento da memória, e depois comparar e substituí-los no momento seguinte. Nesta diferença de tempo , os dados podem ter mudado, o que leva ao problema ABA;

Solução: parte do problema é resolvido adicionando o número da versão (versão),

AQS é um sincronizador de fila abstrato

O AQS mantém um estado de variável de recurso compartilhado com semântica volátil (suportando visibilidade sob vários threads) e uma fila de espera de thread FIFO (quando o estado de competição multithread é bloqueado, ele entrará nesta fila). java.util.concurrent.locks.AbstractQueuedSynchronizerClasse abstrata, referida como AQS

img

A forma como AQS compartilha recursos: exclusivos e compartilhados

AQS fornece dois modos: modo exclusivo e modo compartilhado por padrão, e a implementação correspondente do JDK tem ReentrantLockeReentrantReadWriteLock

Exclusivo: apenas um thread pode ser executado, a implementação JAVA específica tem ReentrantLock

Compartilhado: vários threads são executados ao mesmo tempo

AQS é implementado com base em volitale e CAS. Um estado de variável do tipo valitale é mantido em AQS para
fazer um número reentrante de bloqueios reentrantes. Bloqueio e liberação de bloqueios também são realizados em torno desta variável.

Insira a descrição da imagem aqui

Análise AQS recomendada


Acho que você gosta

Origin blog.csdn.net/weixin_44313584/article/details/114695205
Recomendado
Clasificación