Compreensão do CAS

O que é CAS?

Compare e defina

public class CASDemo{
	public static void main(String[] args){
		AtomicInteger atomicInteger=new AtomicInteger(5);
		
		boolean flag1=atomicInteger.compareAndSet(5,2019);
		//result==2019
		int result1=atomicInteger.get();
		
		boolean flag2=atomicInteger.compareAndSet(5,2001);
		//修改失败,result==2019
		int result1=atomicInteger.get();
	}
}

atomicInteger.compareAndSet (a, b)

1) O valor anterior é o valor esperado, e o valor da memória física esperada é igual a este valor

2) Se o valor real for igual ao esperado, altere o valor para be grave-o na memória física. Se for diferente, não o escreva.

 

Princípio básico do CAS

Método getAndAddInte () de classe insegura + pensamento CAS

var1 --- próprio objeto AtomicIntger

var2 --- O endereço de referência do valor do objeto

var4 --- O valor que precisa ser alterado

var5 --- O valor real na memória principal encontrado usando var1 e var2

Use o valor atual do objeto para comparar com var5:

Se for o mesmo, atualize var5 + var4 e retorne verdadeiro

Se eles forem diferentes, continue pegando o valor e compare novamente até que a atualização seja concluída

 

Aqui estão os motivos para usar CAS em vez de bloqueios sincronizados:

Se bloqueios são usados, a consistência é garantida, mas a simultaneidade é reduzida. O modelo do-while pode ser usado para obter rotação e garantir a simultaneidade

 

Suponha que dois threads, thread A e thread B, executem a operação getAndAddInt ao mesmo tempo:

1) O valor original do valor no AtomicInteger é 3, ou seja, o valor do AtomicInteger na memória principal é 3. De acordo com o modelo JMM, o encadeamento A e o encadeamento B guardam, cada um, uma cópia do valor 3 para sua respectiva memória de trabalho

2) O thread A obtém o valor 3 por meio de getIntVolatile (var1, var2), então o thread A é suspenso

3) O thread B também obtém o valor 3 por meio do método getIntVolatile . Nesse momento, o thread B não está suspenso e executa o método compareAndSwapInt . O valor da memória de comparação também é 3, e o valor da memória foi modificado com êxito para 4

4) Neste momento, o encadeamento A retoma, executa o método compareAndSwapInt e descobre que o valor número 3 em sua mão é inconsistente com o valor número 4 da memória principal, indicando que o valor foi modificado por outros encadeamentos primeiro, então a modificação do thread A falha desta vez, só consigo lê-lo novamente

5) O thread A readquire o valor do valor, porque o valor da variável é modificado por volatile, então outros threads o modificam, o thread A sempre pode ver, o thread A continua a executar compareAndSwapInt para comparação e substituição até ter sucesso

 

Resumindo

CASO:

Compare o valor na memória de trabalho atual com o valor na memória principal, se eles forem iguais, execute a operação especificada, caso contrário, continue a comparar até que os valores na memória principal e na memória de trabalho sejam consistentes

 

Aplicação CAS:

O CAS tem 3 operandos a serem modificados o valor de memória V, o antigo valor esperado A e o valor atualizado B. Se e somente se o valor esperado A e o valor de memória V forem iguais, modifique a memória V para B, caso contrário as instruções não serão realizadas. Repita o processo acima até ter sucesso

 

Desvantagens do CAS:

1) Longo tempo de ciclo e alta sobrecarga (do-while)

2) Garantir apenas o funcionamento atômico de uma variável compartilhada

3) Traga o problema ABA (consulte a postagem do blog https://blog.csdn.net/di_ko/article/details/115066900 )

 

 

Acho que você gosta

Origin blog.csdn.net/di_ko/article/details/115065990
Recomendado
Clasificación