[Código fuente JUC] Análisis de código fuente atómico

En el paquete java.util.concurrent.atomic, hay muchas clases de operaciones atómicas al comienzo de Atomic. Cuando se trata de los tipos de números de uso común en Java, existe básicamente una clase de operación atómica atómica correspondiente, como se muestra en la siguiente figura:
descripción de la imagen
La clase de operación atómica al comienzo de Atomic es segura para subprocesos en escenarios de alta concurrencia, y podemos usarla con confianza.

1. Entero atómico

Es principalmente para llamar a la operación CAS de la clase Unsafe. Lo siguiente es parte del código fuente de AtomicInteger:

public class AtomicInteger extends Number implements java.io.Serializable {
    
    
    
    // 注:value是被volatile修饰的
    private volatile int value;

    // 初始化
    public AtomicInteger(int initialValue) {
    
    
        value = initialValue;
    }
    
    // 得到当前值
    public final int get() {
    
    
        return value;
    }
    
    // 自增 1,并返回自增之前的值    
    public final int getAndIncrement() {
    
    
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
    
    // 自减 1,并返回自增之前的值    
    public final int getAndDecrement() {
    
    
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }
}

A partir del código fuente, podemos ver que todos los métodos de operación seguros para subprocesos se implementan utilizando métodos inseguros en la parte inferior. Los métodos inseguros anteriores no están implementados en Java y son todos seguros para subprocesos.

2.Referencia atómica

AtomicInteger es aumentar y disminuir el valor del tipo int. ¿Qué pasa si el objeto Atomic es una clase personalizada? Java también proporciona una clase de operación atómica para objetos personalizados llamada AtomicReference. El objeto operable de la clase AtomicReference es genérico, por lo que admite clases personalizadas. La capa inferior no tiene un método de autoincremento. El método de operación se puede pasar como un parámetro de función. El código fuente es el siguiente:

// 对 x 执行 accumulatorFunction 操作
// accumulatorFunction 是个函数,可以自定义想做的事情
// 返回老值
public final V getAndAccumulate(V x,BinaryOperator<V> accumulatorFunction) {
    
    
    // prev 是老值,next 是新值
    V prev, next;
    // 自旋 + CAS 保证一定可以替换老值
    do {
    
    
        prev = get();
        // 执行自定义操作
        next = accumulatorFunction.apply(prev, x);
    } while (!compareAndSet(prev, next));
    return prev;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43935927/article/details/108718208
Recomendado
Clasificación