Las variables locales son seguras para subprocesos, ¿por qué?

Este artículo se comparte desde HUAWEI CLOUD Community " [Alta concurrencia] ¿Por qué las variables locales son seguras para subprocesos? ", Autor: Glaciar.

prefacio

Cuando varios subprocesos acceden a variables compartidas al mismo tiempo, puede causar problemas de concurrencia. Entonces, si la variable se coloca dentro del método, ¿sigue habiendo un problema de concurrencia? Si no hay problemas de simultaneidad, ¿por qué no debería haber problemas de simultaneidad?

La famosa sucesión de Fibonacci

Recuerdo que cuando estábamos en la escuela, todos nos encontramos con ese problema, imprimiendo la secuencia de Fibonacci. La sucesión de Fibonacci es una sucesión de este tipo: 1, 1, 2, 3, 5, 8, 13, 21, 34..., es decir, el primer y el segundo elemento son 1, a partir del tercer elemento, cada Cada elemento es igual a la suma de los 2 elementos anteriores. Podemos usar el siguiente código para generar la secuencia de Fibonacci.

//生成斐波那契数列
public int[] fibonacci(int n){
    //存放结果的数组
    int[] result = new int[n];
    //数组的第1项和第2项为1
    result[0] = result[1] = 1;
    //计算第3项到第n项
    for(int i = 2; i < n; i++){
        result[i] = result[i-2] + result[i-1];
    }
    return result;
}

Suponiendo que hay muchos subprocesos que llaman al método fibonacci() al mismo tiempo para generar la secuencia de Fibonacci , ¿habrá un problema de seguridad de subprocesos para el resultado de la variable local en el método? ¡La respuesta es no! !

A continuación, analizaremos en profundidad por qué no hay problema de seguridad de subprocesos con variables locales.

¿Cómo se ejecuta el método?

Tomemos las siguientes tres líneas de código como ejemplo.

int x = 5;
int[] y = fibonacci(x);
int[] z = y;

Cuando llamamos a fibonacci(x), la CPU primero debe encontrar la dirección del método fibonacci() y luego saltar a esta dirección para ejecutar el código. Después de la ejecución, necesita regresar y encontrar la dirección de la siguiente declaración del método de llamada, que es int [] z = la dirección de y, y luego salta a esta dirección para ejecutar. Podemos simplificar este proceso como se muestra en la siguiente figura.

Cabe señalar aquí que la CPU encontrará los parámetros y la dirección de retorno del método de llamada a través del registro de pila.

Por ejemplo, hay tres métodos A, B y C, y la relación de llamada es que A llama a B y B llama a C. En tiempo de ejecución, se construirá la pila de llamadas correspondiente.Podemos usar la siguiente figura para representar simplemente esta pila de llamadas.

Cada método tendrá su propio marco de pila independiente en la pila de llamadas, y cada marco de pila tiene los parámetros y la dirección de retorno requeridos por el método correspondiente. Cuando se llama a un método, se crea un nuevo marco de pila y se coloca en la pila de llamadas; cuando el método regresa, el marco de pila correspondiente se extrae automáticamente.

Podemos decir esto: el marco de pila se crea cuando se llama a un método y "muere" cuando el método regresa.

¿Dónde se almacenan las variables locales?

El alcance de las variables locales está dentro del método, cuando se ejecuta el método, las variables locales son inútiles. Se puede decir que cuando el método regresa, las variables locales "mueren". En este punto, pensaremos en el marco de la pila de la pila de llamadas. Sí, las variables locales se almacenan en la pila de llamadas. En este punto, podemos representar la pila de llamadas del método con la siguiente figura.

Mucha gente sabe que las variables locales se almacenan en la pila. Si una variable necesita cruzar los límites del método, debe crearse en el montón.

pila de llamadas e hilo

Dos hilos pueden llamar al mismo método con diferentes parámetros al mismo tiempo. Entonces, la pregunta es, ¿cuál es la relación entre la pila de llamadas y el hilo? La respuesta es: cada subproceso tiene su propia pila de llamadas independiente. Podemos usar el siguiente diagrama para representar simplemente esta relación.

En este punto, estamos viendo la pregunta al principio de lo siguiente: ¿Hay problemas de concurrencia con variables locales dentro de los métodos de Java? ¡La respuesta es que no hay problema de concurrencia! Debido a que cada subproceso tiene su propia pila de llamadas, las variables locales se almacenan en la pila de llamadas respectiva del subproceso y no se compartirán, por lo que, naturalmente, no hay problema de concurrencia.

cierre de rosca

Dado que las variables locales del método no se compartirán con otros subprocesos, no habrá problemas de concurrencia. Esta técnica de resolución de problemas también se denomina confinamiento de subprocesos. La explicación oficial es: acceder a los datos solo dentro de un solo hilo. Dado que no se comparte, no hay problemas de concurrencia incluso si no configura la sincronización.

Haga clic en Seguir para conocer las nuevas tecnologías de HUAWEI CLOUD por primera vez~

Supongo que te gusta

Origin blog.csdn.net/devcloud/article/details/124018436
Recomendado
Clasificación