Arquitectura de software-Serie distribuida Programación concurrente Bloqueo Bloqueo y limitación de herramientas

 Aunque la programación multiproceso mejora en gran medida la eficiencia, también conlleva ciertos peligros ocultos. Por ejemplo, si dos subprocesos insertan datos únicos en una tabla de base de datos al mismo tiempo, es posible que los mismos datos se inserten en la base de datos. Hoy discutiremos juntos los problemas de seguridad de los subprocesos y qué mecanismos se proporcionan en Java para resolver los problemas de seguridad de los subprocesos. Código fuente: https://github.com/limingios/netFuture/blob/master/JSR133 versión china.pdf

Arquitectura de software-Serie distribuida Programación concurrente Bloqueo Bloqueo y limitación de herramientas

sincronizado y volátil

JSR133 http://www.cs.umd.edu/~pugh/java/memoryModel
FIFO (Primera entrada, primera salida) simplemente significa primero en entrar, primero en salir.

  • ¿Qué es un bloqueo de objeto?

    El bloqueo de objeto, también llamado bloqueo de método, es para una instancia de objeto. Solo declara en una determinada ubicación de memoria del objeto para identificar si el objeto tiene un bloqueo, por lo que solo bloqueará el objeto actual y no otros objetos. El bloqueo de la instancia tendrá algún impacto, y los diferentes objetos no se bloquearán al acceder al mismo método modificado por sincronizado.

  • Que es un trivial

    El bloqueo de clase es bloquear toda la clase. Cuando hay varios subprocesos para declarar objetos de esta clase, se bloqueará hasta que el objeto con este bloqueo de clase se destruya o el bloqueo de clase se libere activamente. En este momento, el subproceso bloqueado está seleccionado Crea un objeto que mantiene el bloqueo de la clase y declara el objeto de la clase. Otros hilos continúan bloqueados.

(Baidu arriba), es decir, en una oración, no importa cuántos objetos, cuántos objetos, comparten más de uno, y solo hay uno, no importa cómo lo llames, se sincronizará

sincronizado

Antes de comprender el uso de la palabra clave sincronizada, veamos primero un concepto: bloqueo de exclusión mutua, como su nombre lo indica: un bloqueo que puede lograr el propósito de acceso de exclusión mutua.

1. Para dar un ejemplo simple: si agrega un bloqueo mutex a un recurso crítico, cuando un subproceso accede al recurso crítico, otros subprocesos solo pueden esperar.
2. En Java, cada objeto tiene una marca de bloqueo (monitor), también conocida como monitor.Cuando varios subprocesos acceden a un objeto al mismo tiempo, el subproceso solo puede acceder a él cuando adquiere el bloqueo del objeto.
3. En Java, puede usar la palabra clave sincronizada para marcar un método o bloque de código. Cuando un subproceso llama al método sincronizado del objeto o accede al bloque de código sincronizado, este subproceso obtiene el bloqueo del objeto y otros subprocesos no pueden temporalmente Para acceder a este método, solo esperando la ejecución de este método o la ejecución del bloque de código, este hilo liberará el bloqueo del objeto, y otros hilos pueden ejecutar este método o bloque de código.

 Sin embargo, hay algunas cosas a tener en cuenta:

  1) Cuando un hilo accede al método sincronizado de un objeto, otros hilos no pueden acceder a otros métodos sincronizados del objeto. La razón de esto es simple, porque un objeto tiene un solo bloqueo, después de que un hilo adquiere el bloqueo del objeto, otros hilos no pueden adquirir el bloqueo del objeto, por lo que no pueden acceder a otros métodos sincronizados del objeto.

  2) Cuando un hilo accede al método sincronizado de un objeto, otros hilos pueden acceder al método no sincronizado del objeto. La razón de esto es muy simple. El acceso a un método no sincronizado no necesita adquirir el bloqueo del objeto. Si un método no se modifica con la palabra clave sincronizada, significa que no utilizará recursos críticos, por lo que otros subprocesos puede acceder a este método.

  3) Si un subproceso A necesita acceder al método sincronizado fun1 de object1 y otro subproceso B necesita acceder al método sincronizado fun1 de object2, incluso si object1 y object2 son del mismo tipo), los problemas de seguridad de subprocesos no surgirán porque son acceder a diferentes objetos, por lo que no existe un problema de exclusión mutua.

Para el método sincronizado o bloque de código sincronizado, cuando ocurre una excepción, la JVM liberará automáticamente el bloqueo ocupado por el subproceso actual, por lo que no se producirá un punto muerto debido a la excepción.

volátil

Una vez que una variable compartida (variable miembro de clase, variable miembro estática de clase) es modificada por volátil, entonces tiene dos capas de semántica:

  1) La visibilidad de esta variable está garantizada cuando operan diferentes subprocesos, es decir, si un subproceso modifica el valor de una variable, el nuevo valor es inmediatamente visible para otros subprocesos.

  2) Está prohibido reordenar las instrucciones.

La palabra clave sincronizada evita que varios subprocesos ejecuten un fragmento de código al mismo tiempo, lo que afectará en gran medida la eficiencia de la ejecución del programa. La palabra clave volátil tiene un mejor rendimiento que sincronizada en algunos casos, pero debe tenerse en cuenta que la palabra clave volátil no puede reemplazar la palabra clave sincronizada., Porque la palabra clave volátil no puede garantizar la atomicidad de la operación. En términos generales, el uso de volátiles debe cumplir las siguientes dos condiciones:

  1) La operación de escritura en la variable no depende del valor actual

  2) La variable no se incluye en la invariante con otras variables.

  De hecho, estas condiciones indican que los valores efectivos que se pueden escribir en variables volátiles son independientes del estado de cualquier programa, incluido el estado actual de la variable.

ReentrantLock

Antes de la versión JDK5.0, el rendimiento del bloqueo reentrante era mucho mejor que el de la palabra clave sincronizada. Después de la versión JDK6.0, sincronizado se ha optimizado mucho y el rendimiento de los dos no es igual, pero el bloqueo reentrante puede reemplace completamente la palabra clave. Además, el bloqueo reentrante también viene con una serie de UBFF altamente forzados: respuesta interrumpible, límite de tiempo de espera de la aplicación de bloqueo, bloqueo justo. Además, se puede usar en combinación con Condition para que esté aún más lleno.

  • Cerradura justa

    El fair lock adquiere el bloqueo del primer nodo de la cola de sincronización cada vez, y el fair lock adquiere el bloqueo cada vez como primer nodo de la cola de sincronización, asegurando el orden absoluto en el momento de solicitar recursos. Para garantizar el orden absoluto de tiempo, los bloqueos justos requieren cambios de contexto frecuentes, mientras que los bloqueos no justos reducirán ciertos cambios de contexto y reducirán la sobrecarga de rendimiento. Por lo tanto, ReentrantLock selecciona bloqueos injustos de forma predeterminada para reducir algunos cambios de contexto y garantizar un mayor rendimiento del sistema.

  • Bloqueo injusto

    Los candados injustos no lo son necesariamente, es posible que el hilo que acaba de soltar el candado pueda adquirir el candado nuevamente. Un bloqueo justo puede hacer que el hilo que acaba de soltar el bloqueo continúe adquiriendo el bloqueo la próxima vez, lo que puede hacer que otros hilos nunca adquieran el bloqueo, lo que resulta en un fenómeno de "inanición".

Proporciona una cola basada en FIFO que se puede utilizar para crear un marco básico para bloqueos u otros dispositivos de sincronización relacionados. El sincronizador (en lo sucesivo denominado sincronizador) utiliza un int para representar el estado y se espera que pueda convertirse en la base para lograr la mayoría de los requisitos de sincronización. El método utilizado es la herencia, la subclase gestiona su estado heredando el sincronizador y necesita implementar su método, la forma de gestión es manipular el estado a través de métodos similares a adquirir y liberar. Sin embargo, la manipulación del estado en un entorno multiproceso debe garantizar la atomicidad, por lo que las subclases deben utilizar los siguientes tres métodos proporcionados por este sincronizador para operar en el estado para captar el estado:

java.util.concurrent.locks.AbstractQueuedSynchronizer.getState()
java.util.concurrent.locks.AbstractQueuedSynchronizer.setState(int)
java.util.concurrent.locks.AbstractQueuedSynchronizer.compareAndSetState(int, int)

Se recomienda definir la subclase como una clase interna de un dispositivo de sincronización personalizado. El sincronizador en sí no implementa ninguna interfaz de sincronización, solo define una serie de métodos de adquisición y otros para su uso. El sincronizador se puede utilizar como modo exclusivo o modo compartido.Cuando se define como modo exclusivo, se bloquea la adquisición de otros subprocesos y el modo compartido puede tener éxito para varios subprocesos.

El sincronizador es la clave para la realización de la cerradura, el sincronizador se utiliza para realizar la semántica de la cerradura y luego el sincronizador se agrega en la realización de la cerradura. Se puede entender así: la API de bloqueo está orientada al usuario y define el comportamiento público de interactuar con el bloqueo, y cada bloqueo debe completar una operación específica a través de estos comportamientos (por ejemplo: se pueden permitir dos subprocesos para agregar Lock, excluyendo más de dos subprocesos), pero la implementación se realiza confiando en el sincronizador; el sincronizador es para el acceso al subproceso y el control de recursos, que define si el subproceso puede obtener recursos y la cola de subprocesos y otras operaciones. Las cerraduras y los sincronizadores son una buena separación de las áreas a las que los dos deben prestar atención. Estrictamente hablando, los sincronizadores se pueden aplicar a otras funciones de sincronización (incluidas las cerraduras) además de las cerraduras.

AbstractQueuedSynchronizer también se llama sincronizador de cola (en lo sucesivo, AQS). Se utiliza para crear bloqueos u otros componentes de sincronización. El marco básico utiliza un estado de variable miembro de tipo int para controlar el estado de sincronización. Cuando state = 0, significa que hay is no El subproceso ocupa el bloqueo del recurso compartido. Cuando el estado = 1, significa que hay un subproceso que está usando la variable compartida y otros subprocesos deben unirse a la cola de sincronización para esperar. AQS utiliza internamente el nodo interno para formar un Cola de sincronización FIFO para completar la cola de bloqueo de adquisición de subprocesos Al mismo tiempo, la clase interna ConditionObject se utiliza para construir la cola de espera. Cuando la condición llama al método wait (), el subproceso se unirá a la cola de espera y cuando la condición llame el método signal (), el hilo se moverá de la cola de espera a la cola de sincronización móvil para bloquear la competencia. Tenga en cuenta que hay dos colas involucradas aquí, una es una cola síncrona, cuando el hilo solicita un bloqueo y espera, se unirá a la cola síncrona para esperar, y la otra es una cola de espera (puede haber varias), llame a la espera () a través del método Condición Después de que se libere el bloqueo, se agregará a la cola de espera.

PD: Hay muchas teorías. Fíjate bien en los puntos clave. El pdf compartido en el código fuente y la introducción de hilos en el sitio web oficial han sido traducidos al chino por los chinos, lo cual es fácil de entender.

Supongo que te gusta

Origin blog.51cto.com/12040702/2660400
Recomendado
Clasificación