Red de conocimiento informático - Aprendizaje de programación - ¿Hay algún problema con los subprocesos múltiples de Java que llaman simultáneamente a métodos estáticos de una clase?

¿Hay algún problema con los subprocesos múltiples de Java que llaman simultáneamente a métodos estáticos de una clase?

Conclusión general: Java es seguro para subprocesos, es decir, cualquier método (incluidos los métodos estáticos) puede ignorar los conflictos de subprocesos, pero existe la premisa de que no puede haber variables globales. Si hay variables globales, debe utilizar el mecanismo de sincronización.

Explícalo desde el principio con el siguiente conjunto de ejemplos contrastantes:

¿Qué sucede cuando se usan métodos estáticos en múltiples subprocesos? En otras palabras, ¿qué pasará si varios subprocesos acceden al método estático de la misma clase? ¿Habrá problemas de seguridad de los hilos?

Prueba de clase pública{

Operación de anulación estática pública(){

// ...haz algo

}

}

Resulta que mientras los datos compartidos por varios subprocesos no se procesen en una función estática, no hay problema de conflicto de recursos cuando varios subprocesos acceden al mismo método estático. Veamos un ejemplo:

La clase pública StaticThread implementa Runnable {

@Override

Public void Runnable(){

// TODO genera automáticamente un código auxiliar de método

acción estática . print();

}

Public static void main(String[] args) {

for(int I = 0; i lt100; i) {

Nuevo hilo (nuevo StaticThread()). start();

}

}

}

Clase pública StaticAction {

pública estática int I = 0;

impresión vacía estática pública() {

int suma =

for(int I = 0; i lt10; i ) {

System.out.print("el paso " i "se está ejecutando.);

suma = I;

}

If ( suma! = 45) {

System.out.println("¡Error de hilo!");

system .out(0);

}

system . out . println(" sum is " sum);

}

}

Los resultados de ejecución reales muestran que cada hilo tiene acceso. a métodos estáticos se ejecuta de forma cruzada, pero esto no afecta el cálculo del valor de la suma en el método estático print() de cada hilo. En otras palabras, los métodos estáticos que no utilizan variables globales en este proceso son seguros en múltiples. subprocesos. Sí, si los métodos estáticos causan problemas de seguridad de subprocesos depende principalmente de si el método estático modifica las variables globales (variables estáticas).

Cuando se utiliza el mismo método estático en varios subprocesos, cada subproceso usa su propia instancia. Copia de campo, * * * posee un campo estático. Por lo tanto, si el método estático no opera en el miembro estático y solo usa el campo de instancia dentro del método, no habrá problemas de seguridad. si el método estático opera en el campo estático, las variables deben manejarse de forma segura mediante acceso mutuamente excluyente en métodos estáticos.

Veamos qué pasa si no usamos acceso mutuamente excluyente: public class StaticAction {

public static int I = 0;

public static void incValue() {

int temp = StaticAction.i

Prueba {

thread .sleeping(1

} catch (Exception e) {

e.printstacktrace();

}

temp;

StaticAction.i = temp

}

}

La clase pública StaticThread implementa Runnable {

@Override

Public void run(){

// TODO automático Stub de método generado

Acción estática. Inc valor();

}

Public static void main(String[] args) {

for(int I = 0; i lt100; i) {

Nuevo hilo (nuevo StaticThread()). start();

}

Pruebe {

thread . sleep(1000); //Deje suficiente tiempo para que el hilo anterior termine de ejecutarse.

} catch(Excepción e) {

e . printstacktrace();

}

system out . . I);

}

}

Los resultados reales de la operación muestran que el valor I es un número aleatorio. Para lograr un acceso mutuamente exclusivo, debemos agregar una palabra clave sincronizada en este momento. Modifique el código de la siguiente manera:

Clase pública StaticAction {

public static int I = 0;

Pública sincronizada static void incValue() {

int temp = StaticAction.i

Prueba {

thread .sleeping(1

} catch (Exception e) {

e.printstacktrace();

}

temp;

StaticAction.i = temp

}

}

La clase pública StaticThread implementa Runnable {

@Override

Public void run(){

// TODO automático Stub de método generado

Acción estática. Inc valor();

}

Public static void main(String[] args) {

for(int I = 0; i lt100; i) {

Nuevo hilo (nuevo StaticThread()).

start();

}

Pruebe {

thread(1000

} catch (Excepción e) {

e . printstacktrace();

}

sistema . println(acción estática . I); >

}

El resultado de la ejecución debe ser 100.

Los métodos estáticos con la palabra clave sincronizado se denominan métodos estáticos sincronizados.

Al acceder a un método estático sincronizado, se obtendrá el objeto "Clase" de la clase, por lo que cuando un subproceso ingresa al método estático sincronizado, el monitor de subprocesos obtiene el bloqueo del objeto de la clase en sí, y otros Los subprocesos no pueden ingresar a la clase. Cualquier método sincronizado estático de la clase. No es como los métodos de instancia en el sentido de que varios subprocesos pueden acceder a diferentes instancias al mismo tiempo para sincronizar los métodos de instancia. En realidad, este es un problema de sincronización de exclusión mutua entre procesos y semáforos en el sistema operativo. Si hay varios métodos estáticos en la misma clase que manejan datos de subprocesos múltiples, entonces se trata de usar semáforos para resolver el problema productor-consumidor. En otras palabras, los métodos estáticos son recursos clave y el acceso a los métodos estáticos pertenece a áreas clave; las modificaciones de variables estáticas son recursos clave y las modificaciones de variables estáticas pertenecen a áreas clave.