[Java] ¿Cuáles son las ideas de implementación de la seguridad de subprocesos en Java?


En la programación multiproceso de Java, la seguridad de los subprocesos es un concepto muy importante. La seguridad de subprocesos generalmente significa que un programa aún puede mantener un comportamiento correcto cuando se ejecutan varios subprocesos al mismo tiempo. Java proporciona muchos métodos para lograr la seguridad de subprocesos, este artículo presentará varias ideas de implementación comunes.
inserte la descripción de la imagen aquí

1. Usa la palabra clave sincronizada

La palabra clave sincronizada es la forma más fundamental de resolver el problema de la seguridad de subprocesos en Java, lo que puede garantizar que el bloque de código se ejecute de forma atómica. sincronizado se puede usar para decorar métodos de instancia, métodos estáticos y bloques de código. El siguiente es el código de muestra del método de instancia modificado sincronizado:

public class Counter {
    
    
    private int count;

    public synchronized void increment() {
    
    
        count++;
    }

    public synchronized int getCount() {
    
    
        return count;
    }
}

En el código anterior, los métodos increment() y getCount() se modifican sincronizados, de modo que solo un subproceso puede acceder a ellos a la vez. Aunque este método es simple, su eficiencia es relativamente baja, porque solo un subproceso puede acceder a estos métodos a la vez.

2. Usa la clase ReentrantLock

La clase ReentrantLock en Java proporciona un mecanismo de sincronización de subprocesos más flexible que sincronizado. ReentrantLock es reentrante, puede interrumpir el subproceso que espera el bloqueo e intentar adquirir el bloqueo a través del método tryLock(). El siguiente es un código de muestra para la seguridad de subprocesos mediante ReentrantLock:

import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    
    
    private int count;
    private ReentrantLock lock = new ReentrantLock();

    public void increment() {
    
    
        lock.lock();
        try {
    
    
            count++;
        } finally {
    
    
            lock.unlock();
        }
    }

    public int getCount() {
    
    
        lock.lock();
        try {
    
    
            return count;
        } finally {
    
    
            lock.unlock();
        }
    }
}

En el código anterior, lock.lock() se usa para adquirir el bloqueo y lock.unlock() se usa para liberar el bloqueo. Al usar ReentrantLock, se debe tener en cuenta que la lógica de adquisición y liberación de bloqueos debe colocarse en un bloque de intento final para garantizar que el bloqueo se libere correctamente.

3. Usa la clase ConcurrentHashMap

ConcurrentHashMap es una implementación de tabla hash segura para subprocesos en Java. ConcurrentHashMap utiliza un mecanismo de bloqueo de segmento para dividir toda la tabla hash en varios segmentos, y varios subprocesos pueden acceder a los elementos en diferentes segmentos al mismo tiempo. Aquí hay un código de ejemplo para la seguridad de subprocesos usando ConcurrentHashMap:

import java.util.concurrent.ConcurrentHashMap;

public class Counter {
    
    
    private ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

    public void increment(String key) {
    
    
        map.put(key, map.getOrDefault(key, 0) + 1);
    }

    public int getCount(String key) {
    
    
        return map.getOrDefault(key, 0);
    }
}

En el código anterior, ConcurrentHashMap se usa para almacenar el valor del contador, y el método de map.put() y map.getOrDefault() se usa para actualizar y obtener el valor del contador. Dado que ConcurrentHashMap es seguro para subprocesos, esta implementación puede garantizar que el valor del contador sea correcto cuando varios subprocesos acceden a él al mismo tiempo.

4. Usa la clase Atómica

La clase Atomic en Java proporciona un conjunto de operaciones atómicas que aseguran que las operaciones se realicen de forma atómica. Las clases atómicas incluyen AtomicBoolean, AtomicInteger, AtomicLong, etc. Aquí hay un código de ejemplo para la seguridad de subprocesos usando AtomicInteger:

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
    
    
    private AtomicInteger count = new AtomicInteger();

    public void increment() {
    
    
        count.incrementAndGet();
    }

    public int getCount() {
    
    
        return count.get();
    }
}

En el código anterior, AtomicInteger se usa para almacenar el valor del contador y el método count.incrementAndGet() se usa para actualizar el valor del contador. Dado que AtomicInteger es seguro para subprocesos, esta implementación puede garantizar que el valor del contador sea correcto cuando varios subprocesos acceden a él al mismo tiempo.

5. Usa la clase ThreadLocal

La clase ThreadLocal permite que cada subproceso tenga su propia copia de variables.Cuando varios subprocesos se ejecutan simultáneamente, cada subproceso puede operar de forma independiente su propia copia de variables, evitando así problemas de seguridad de subprocesos. El siguiente es un código de muestra para la seguridad de subprocesos mediante ThreadLocal:

public class Counter {
    
    
    private ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);

    public void increment() {
    
    
        threadLocal.set(threadLocal.get() + 1);
    }

    public int getCount() {
    
    
        return threadLocal.get();
    }
}

En el código anterior, la clase ThreadLocal se usa para almacenar el valor del contador, y los métodos threadLocal.set() y threadLocal.get() se usan para actualizar y obtener el valor del contador. Dado que cada subproceso tiene su propia copia de la variable, esta implementación garantiza que el valor del contador sea correcto cuando varios subprocesos acceden a él al mismo tiempo.

Resumir

Este artículo presenta varias formas de lograr la seguridad de subprocesos en Java, incluida la palabra clave sincronizada, la clase ReentrantLock, la clase ConcurrentHashMap, la clase Atomic, la clase ThreadLocal, etc. Cada método tiene sus características y escenarios aplicables, y se debe seleccionar el método apropiado de acuerdo con las necesidades reales. En aplicaciones prácticas, para mejorar mejor el rendimiento y la concurrencia del sistema, se pueden usar varios métodos en combinación para lograr la seguridad de subprocesos.

Supongo que te gusta

Origin blog.csdn.net/u011397981/article/details/130653239
Recomendado
Clasificación