Java Multithread-2-CAS

2. CAS

1. Concepto

CAS (compareAndSwap), compare e intercambie

La operación CAS requiere la entrada de dos valores, un valor antiguo (el valor antes de la operación) y un nuevo valor (el valor que se va a operar). Durante la operación, primero compare si el valor anterior ha cambiado, si no hay cambio, luego cambie al nuevo valor, de lo contrario no cambie

Se utiliza principalmente para java.util.concurrentla implementación de bajo nivel de múltiples clases (bloqueo, atómico) en el paquete. La clase principal es sun.misc.Unsafeque la mayoría de los métodos de la clase son métodos nativos, porque llama a las instrucciones de ensamblaje en la parte inferior del sistema operativo

2. Java implementa operaciones atómicas

Además de usar bloqueos, también puede usar spin + CAS

Spin es para reducir la sobrecarga del cambio de contexto de hilo

3. Los tres problemas principales de la implementación de CAS de operaciones atómicas

[1] Problema de ABA

Descripción del problema: Porque la operación CAS requiere comparación. Si el valor anterior se ha modificado muchas veces, y el último valor actualizado resulta ser el valor anterior comparado esta vez, actualizará la situación que no debería haberse actualizado.

Solución: use el número de versión para agregar juicio. No solo compare si el valor es el mismo, sino que también compare si el número de versión es lógico

[2] El tiempo de centrifugado prolongado genera gastos generales elevados

Descripción del problema: si la operación CAS no ha tenido éxito, hará que el tiempo de giro sea demasiado largo, lo que traerá una sobrecarga de ejecución muy grande a la CPU (mayor uso de la CPU)

Solución: si la JVM puede admitir la instrucción de pausa proporcionada por el procesador, se mejorará la eficiencia. Duerme un rato

[3] Solo garantiza el funcionamiento atómico de una variable compartida

Descripción del problema: la operación CAS solo puede comparar un valor al mismo tiempo

Solución: bloquear. O combine múltiples variables compartidas en una variable compartida para operar, como usarjava.util.concurrent.atomic.AtomicReference

4. clases relacionadas con java.util.concurrent.atomic

【1】 AtomicInteger

AtomicInteger atomicInteger = new AtomicInteger(10);
boolean compareAndSet = atomicInteger.compareAndSet(10, 20);
System.out.println(compareAndSet); // true
System.out.println(atomicInteger.get()); // 20

System.out.println(atomicInteger.incrementAndGet()); // 21
System.out.println(atomicInteger.decrementAndGet()); // 20

【2】 Referencia atómica

Object obj1 = new Object();
System.out.println("obj1:" + obj1);

AtomicReference<Object> atomicReference = new AtomicReference<Object>(obj1);

Object obj2 = new Object();
System.out.println("obj2:" + obj2);

Object getAndSet = atomicReference.getAndSet(obj2);
System.out.println("旧值:" + getAndSet); // obj1
System.out.println("新值:" + atomicReference.get()); // obj2

【3】 AtomicStampedReference

Object obj1 = new Object();
int stamp = 1;
AtomicStampedReference<Object> atomicStampedReference = new AtomicStampedReference<Object>(obj1, stamp);

Object obj2 = new Object();
System.out.println("obj2:" + obj2);

stamp = 2;
boolean compareAndSet = atomicStampedReference.compareAndSet(obj1, obj2, 1, stamp);
System.out.println(compareAndSet); // true
System.out.println(atomicStampedReference.getReference()); // obj2
System.out.println(atomicStampedReference.getStamp()); // 2

Supongo que te gusta

Origin blog.csdn.net/adsl624153/article/details/103865205
Recomendado
Clasificación