Principio y aplicación de bloqueo de lectura y escritura reentrante

Tabla de contenido

1. Introducción

2. Aplicación

3. Principio


1. Introducción

Cuando las operaciones de lectura son mucho más altas que las operaciones de escritura , use bloqueos de lectura y escritura en este momento para permitir que las lecturas y lecturas sean simultáneas y mejorar el rendimiento.

Similar al bloqueo compartido select...from...lock in share mode en la base de datos  

Proporcione una clase de contenedor de datos con un método de lectura () que usa un bloqueo de lectura para proteger los datos y un método de escritura () que usa un bloqueo de escritura para proteger los datos

Dos subprocesos de lectura y lectura no se excluyen mutuamente, lectura y escritura y escritura y escritura se excluyen mutuamente

Precauciones:

  • Los bloqueos de lectura no admiten variables de condición
  • La actualización no es compatible durante el reingreso : la adquisición de un bloqueo de escritura mientras se mantiene un bloqueo de lectura hará que la adquisición del bloqueo de escritura espere para siempre, y el bloqueo de lectura debe liberarse antes de adquirir el bloqueo de escritura
  • Soporte de degradación durante el reingreso : mantener un bloqueo de escritura puede adquirir un bloqueo de lectura

2. Aplicación

Actualizamos la caché con dos operaciones

Primero elimine el caché: debemos considerar este problema cuando implementamos el caché y la base de datos. Por ejemplo, cuando hay un subproceso que consulta la base de datos y se prepara para actualizar los datos de la base de datos al caché, el subproceso b cambia la base de datos. Esto a veces, si la actualización es exitosa, el caché será inconsistente con los datos que se han cambiado en la base de datos, y luego los datos antiguos en el caché siempre se usarán más tarde.

Actualice la base de datos primero: es mejor actualizar la base de datos primero, y la inconsistencia de la base de datos de caché será menor, pero para garantizar una consistencia sólida, aún se requieren bloqueos. Porque cuando la base de datos se cambia primero y el caché no se ha eliminado, la consulta en este momento es todos los datos antiguos, lo cual es inconsistente

El bloqueo aquí se puede optimizar con bloqueos de lectura y escritura

  • Bloqueo de lectura : si hay datos en el caché, consulte el caché y recuerde liberar el bloqueo de lectura aquí (porque si no es necesario consultar el caché, se requiere un bloqueo de escritura y no puede obtener un bloqueo de escritura si mantener un bloqueo de lectura)
  • Bloqueo de escritura : no hay datos en el caché, consulte desde la base de datos y escriba en el caché (si muchos subprocesos toman el bloqueo, puede haber muchas colas, pero esto solo necesita uno, por lo que se requieren verificaciones dobles)
  • Bloqueo de escritura : actualice, primero actualice la base de datos y luego elimine el caché

Este tipo de optimización se refleja principalmente en la situación de que la lectura y la escritura se pueden compartir en escenarios donde se realizan más lecturas y menos escrituras. Sin embargo, si desea mejorar aún más la concurrencia, puede dividirla de una manera más detallada. . Y esta situación solo es adecuada para escenarios independientes.

3. Principio

El bloqueo de lectura y escritura utiliza el mismo sincronizador de sincronización, por lo que la cola de espera, el estado, etc. también son los mismos

Pero también hay una diferencia. Su estado ha cambiado, porque el estado del bloqueo de lectura y el bloqueo de escritura deben registrarse. Los 16 bits superiores registran el bloqueo de lectura y los 16 bits inferiores registran el bloqueo de escritura . Otros procesos son similares a reentrantlock

Bloqueo de escritura

No hay diferencia entre agregar un bloqueo de escritura y antes. Verifique primero el estado. Si el estado es igual a 0, significa que no se ha agregado ni el bloqueo de lectura ni el bloqueo de escritura, y luego juzgue un método (si el bloqueo injusto devuelve falso directamente, compruebe si hay un bloqueo justo. Tiene que ponerse en cola y volver si no lo hace), luego cas para bloquear, y si tiene éxito, establezca el subproceso de retención de bloqueo actual en ExclusiveOwnerThread. Si se considera que el estado no es 0, entonces se puede agregar el bloqueo de lectura o se puede agregar el bloqueo de escritura. Si se agrega el bloqueo de lectura, será mutuamente excluyente y devolverá falso directamente. Si el agregado es un bloqueo de escritura, mira si lo agregas tú mismo, lo único es volver a ingresar el estado de bloqueo de escritura + 1. Si es de otra persona, devolverá falso, por supuesto, si el número de reingresos supera un número determinado de veces , 65535 también generará una excepción.

añadir bloqueo de lectura

Primero juzgue el estado y luego verifique si la parte del bloqueo de escritura es 0. Si no es 0 && ¿es la persona que agregó el bloqueo de escritura? Los bloqueos de lectura no se pueden agregar a los bloqueos de escritura). Si es -1, volverá a juzgar si puede obtener el bloqueo de lectura, o si no puede, entrará en la cola de bloqueo y esperará.

Aviso:

Aunque sus subprocesos bloqueados están todos en una cola de bloqueo, sus estados son diferentes debido a los diferentes bloqueos que solicitan. Los que esperan un bloqueo de lectura están en el estado compartido, los que esperan un bloqueo de escritura están en el estado ex y los los estados de los nodos anteriores son - 1 tiene la responsabilidad de activar los siguientes nodos, pero el estado del último nodo es 0 y no hay necesidad de despertar más tarde

liberación de bloqueo de escritura

Reduzca directamente el número de estados en -1 y luego verifique si es 0. Si no es 0, la reentrada del bloqueo se reduce en 1 y devuelve falso, si es 0 después de la reducción, devuelve verdadero. Si devuelve verdadero, establezca el subproceso de retención de bloqueo actual en nulo y luego verifique el nodo principal de la cola bloqueada.Si hay un estado de corte de gas que no es igual a 0, actívelo. Después de despertar, continúe ciclando para competir por el bloqueo y descubra que nadie tiene el bloqueo, agregue un bloqueo de escritura a cas, agregue un bloqueo de alto nivel y luego devuelva 1 para indicar que el bloqueo se realizó correctamente. Entonces es necesario despertar de la cola bloqueada, si es un bloqueo de lectura, despertar.

Después de cambiar el nodo en la cola de bloqueo, obtenga el siguiente del nodo actual. Si el siguiente nodo es compartido y desea agregar un bloqueo de lectura, cambie el -1 del nodo actual a 0 y luego despierte el siguiente nodos, y luego deje que el estado del bloqueo de lectura sea +1 (varios subprocesos pueden leer el bloqueo para aumentar el conteo) y luego elimine este nodo en la cola bloqueada y cámbielo al siguiente, y luego continúe juzgando si el el siguiente es un nodo de lectura, si es un duplicado.

leer liberación de bloqueo

Obtenga el estado del estado, luego establezca el estado de bloqueo de lectura en -1, y luego use cas para establecer el estado para ver si puede tener éxito. Después del éxito, juzgue si es 0. Si es verdadero, no es 0 o falso . Si es 0, vaya al nodo principal de la cola bloqueada, si el estado del nodo principal es -1, despierte ese nodo, y si no es -1, intente nuevamente.

Supongo que te gusta

Origin blog.csdn.net/weixin_54232666/article/details/131157121
Recomendado
Clasificación