Todo sobre subprocesos múltiples: los conceptos básicos.En este momento, posibles problemas al hacer subprocesos múltiples y cómo… | por GodDB | febrero de 2022
Esta vez, veremos posibles problemas, soluciones y enfoques cuando se utilizan subprocesos múltiples.
Estos problemas se dividen en general en dos categorías.
La visibilidad es cuando diferentes subprocesos pueden estar mirando la misma variable global pero con diferentes valores internos.
Básicamente, las inconsistencias de datos pueden ocurrir en diferentes hilos por razones como la optimización, porque todos los datos no se leen desde la memoria principal, sino a través de su propio caché.
Para evitar esto, en la variable global Volatile
Las inconsistencias de datos se pueden resolver leyendo de la memoria principal agregando la palabra clave ‘,’.
ejemplo
Este código está efectivamente atascado en un bucle infinito debido a problemas de visibilidad.
Caso práctico de uso
Se aplican todas las estructuras de datos que manejan subprocesos múltiples reales.
java.util.concurrent.atomic.*
androidx.lifecycle.livedata
En algunos casos, debe usar el valor actual de un objeto compartido para crear un nuevo valor mientras realiza subprocesos múltiples. En este caso, surgen problemas de sincronización de subprocesos múltiples.
Por ejemplo, si varios subprocesos incrementan el valor anterior de un objeto compartido, ¿cuál será el resultado?
Estoy en 3 subprocesos ++ con 1000 cada uno, por lo que debería obtener 3000, pero el resultado no lo es. 3000 puede o no aparecer.
La razón es que cuando cada subproceso lee y escribe, el tiempo no es secuencial.
Entonces, ¿cuáles son algunas formas de hacer esto en secuencia?
Sincrónico
Una forma muy sencilla y fácil de acceder a los objetos. Synchronized
es lidiar con eso.
Al configurar el mutex para acceder al objeto de valor, solo un subproceso puede acceder al objeto de valor, de modo que varios subprocesos puedan leer y escribir secuencialmente.
No solo eso synchronize( mutex_target )
Depende del ámbito en el que se asigna el mutex.
함수@synchronized
La sincronización se realiza a nivel de objeto. Otras funciones no sincronizadas no se ven afectadas.
sincronizar (esto)
Equivalente a la palabra clave de función @synchronized. La sincronización ocurre a nivel de objeto, otras partes no sincronizadas no se ven afectadas.
sincronización (clase)
La sincronización se realiza por clase. Otras partes no sincronizadas no se ven afectadas.
sincronización (instancia de campo)
La sincronización se realiza por instancia de campo. No afecta la sincronización con otras instancias de campo.
¿Los vamos a mezclar?
Al ver todas las sincronizaciones de sincronización enumeradas anteriormente,
La misma unidad, objectSynchronizedFunc(), se ve afectada por functionSynchronizedFunc() y genera el registro después de 10 segundos.
Esto permite confirmar que no se ven afectados a menos que estén al mismo nivel.
Por ejemplo, aplicar la sincronización a nivel de clase no afecta la sincronización por objeto y especificar la sincronización por objeto no afecta la sincronización basada en instancias por campo.
Además, la funcionalidad de sincronización no se finaliza aquí, sino que utiliza monitores y, en algunos casos, monitores, para liberar bloqueos y delegados.
Por supuesto, el uso de monitores no es el enfoque recomendado, es una función que no se proporciona en Kotlin.
Entonces, en términos de aprendizaje, en Java synchronized
Veamos cómo delegar usando un monitor después de delegar.
monitor
Proporcionado por el lenguaje Java para manejar la sincronización de manera más flexible en un entorno de subprocesos múltiples.
Mediante el uso de monitores, puede manejar la sincronización de manera más flexible al delegar el control a otros subprocesos en algunos casos en el caso de un mutex.
esperar(), notificar(), notificar a todos()
- wait () : libera el bloqueo retenido actualmente y lo coloca en un estado de espera.
- notificar(): despierta un hilo en espera.
- notificarTodos(): despierta todos los subprocesos en espera.
ejemplo
Hice un ejemplo de bucle 10 veces sobre un objeto compartido que se silencia entre sí en dos hilos.
Este es un ejemplo de pasar la propiedad a otro subproceso a través de wait() cuando cada índice de bucle se vuelve par.
Una cosa a tener en cuenta al usar el monitor es que si se llama a wait(), las siguientes líneas no se ejecutan y están en estado de espera. Por lo tanto, debe llamar a notificar () para activar el hilo antes de llamar a esperar ().
Y cuando el bloqueo se libera de otro subproceso, regresa y reanuda la ejecución en el punto posterior a la espera().