[JUC Advanced] 09. Acerca de la actualización de bloqueo

Tabla de contenido

1. Introducción

2. Revisión

2.1, encabezado de objeto y diseño de memoria

2.2 Revisión de las cuatro esclusas principales

3. Estado de transición

3.1 Estado de bloqueo

3.1.1, sin estado de bloqueo

3.1.2 Estado de bloqueo de polarización

3.1.3, estado de bloqueo ligero

3.1.4, estado de bloqueo pesado

3.2 Condiciones de transición de estado

3.2.1, sin bloqueo -> bloqueo sesgado

3.2.2, bloqueo sesgado -> sin bloqueo

3.2.3, bloqueo sesgado -> bloqueo ligero

3.2.4, candado ligero -> candado pesado

3.2.5 Cerradura pesada -> Cerradura ligera

4. Proceso de actualización de bloqueo

5. ¿Se puede degradar el bloqueo?


1. Introducción

En la programación concurrente, los bloqueos son un mecanismo importante para garantizar la seguridad de los subprocesos. Sin embargo, el rendimiento de los bloqueos tradicionales puede verse limitado en escenarios de alta simultaneidad. Para resolver este problema, JUC introduce el concepto de escalada de bloqueos, que mejora el rendimiento de la concurrencia ajustando dinámicamente el estado de los bloqueos en tiempo de ejecución. Anteriormente introdujimos el conocimiento de bloqueos sin bloqueo, bloqueos sesgados, bloqueos livianos, bloqueos giratorios y bloqueos pesados. Estos son en realidad los varios estados que se convertirán debido a la optimización del bloqueo en JUC, que es la actualización de bloqueo que escuchamos con frecuencia.

2. Revisión

2.1, encabezado de objeto y diseño de memoria

Si no comprende bien este conocimiento, puede leer "[JUC Advanced] 03. Encabezado de objeto Java y diseño de memoria". Aquí hay una breve reseña.

El diseño de los objetos Java almacenados en la memoria del montón se puede dividir en tres partes: encabezado del objeto (Encabezado), datos de la instancia (Datos de la instancia) y relleno de alineación (Padding). El encabezado del objeto (Header) contiene dos partes de información: el campo de marca (Mark Word) y el puntero del objeto Class (Class Pointer).

Entre ellos, el campo de marca (Mark Word) se usa para almacenar los datos de tiempo de ejecución del propio objeto, como HashCode (código hash), edad de generación de GC, indicador de estado de bloqueo, bloqueo retenido por el subproceso, ID de subproceso sesgado, marca de tiempo sesgada , etc. El puntero de objeto de clase (Puntero de clase) es el puntero del objeto a su tipo de metadatos, y la JVM utiliza este puntero para determinar de qué clase es una instancia el objeto.

Cuando el objeto tiene varios niveles de bloqueos, el campo de marca (Mark Word) almacenará los bits de marca relevantes, la identificación del subproceso y otra información.

2.2 Revisión de las cuatro esclusas principales

Anteriormente introdujimos el conocimiento de varias cerraduras en detalle. Aquí hay un resumen de las características relevantes de varias cerraduras.

Tipo de bloqueo

característica

Naturaleza

principio

ventaja

defecto

Escenas a utilizar

gastos generales de rendimiento

sin candado

sin bloqueo, sin sincronización

Operación atómica a través de CAS

Control de concurrencia usando operaciones atómicas

Sin bloqueo, evitando la sobrecarga del bloqueo y cambio de subprocesos

La espera de giro consume recursos de la CPU

Alta concurrencia y baja contención

Bajo, solo implica pérdida de rendimiento de las operaciones atómicas

Bloqueo de polarización

adecuado para un solo hilo

Identificar el titular por ID de subproceso

Al adquirir el bloqueo por primera vez, registre el ID del hilo en la palabra de marca del objeto de bloqueo.

Evita la competencia de subprocesos múltiples y acelera las rutas de ejecución de un solo subproceso

Los bloqueos sesgados se revocarán cuando compitan varios subprocesos, lo que generará una sobrecarga adicional

Subproceso único que con frecuencia adquiere bloqueos

Bajo, solo implica operaciones de escritura y comparación de ID de subprocesos

candado ligero

girar esperar

Implementado por CAS y spin

Cuando se revoca el bloqueo sesgado o la competencia de subprocesos múltiples, use CAS para reemplazar Mark Word

Reduce la sobrecarga del bloqueo y la conmutación de subprocesos, adecuado para la competencia de bloqueo a corto plazo

La espera de giro consume recursos de la CPU

contención de bloqueo a corto plazo

Moderado, que involucra operaciones CAS y esperas de giro

cerradura de peso pesado

bloquear

Uso de exclusión mutua del sistema operativo

Cuando la competencia de subprocesos sea feroz, utilice el mecanismo de exclusión mutua proporcionado por el sistema operativo

Puede resolver de manera efectiva la competencia de subprocesos múltiples y garantizar la seguridad y corrección de los datos.

Se requiere el bloqueo y la conmutación de subprocesos, y la sobrecarga es grande

Competencia de bloqueo a largo plazo para garantizar la seguridad y corrección de los datos

Alto, que implica bloqueo de subprocesos, conmutación y programación del sistema operativo

Se puede ver que en términos de sobrecarga de rendimiento: sin bloqueo ≤ bloqueo sesgado ≤ bloqueo ligero ≤ bloqueo pesado. Si tiene algo de experiencia en programación, debe ser consciente de que el proceso de actualización inevitablemente afectará la sobrecarga de rendimiento, por lo que el proceso de actualización de bloqueo (transición de estado) se puede deducir de acuerdo con la distribución de la sobrecarga de rendimiento. La respuesta es sí.

3. Estado de transición

3.1 Estado de bloqueo

3.1.1, sin estado de bloqueo

En el estado sin bloqueo, los subprocesos pueden acceder libremente a los recursos compartidos sin restricciones de bloqueo ni competencia. Las carreras de datos y los problemas de seguridad de subprocesos pueden ocurrir cuando varios subprocesos acceden al mismo recurso compartido al mismo tiempo.

3.1.2 Estado de bloqueo de polarización

Cuando solo un subproceso accede al bloque de código sincronizado, la JVM marcará el objeto como un estado de bloqueo sesgado. El propósito de los candados sesgados es reducir los gastos generales de los candados en ausencia de competencia. Cuando el subproceso ingresa al bloque de código de sincronización por primera vez, la JVM registrará la ID del subproceso en el encabezado del objeto como la ID del subproceso actual y establecerá el estado del encabezado del objeto como un bloqueo sesgado. Posteriormente, cuando el subproceso ingresa nuevamente al bloque de código de sincronización, ingresa directamente al estado de sincronización sin realizar operaciones de sincronización adicionales.

3.1.3, estado de bloqueo ligero

Cuando hay una contención ligera entre varios subprocesos, la JVM marcará el objeto como un estado de bloqueo ligero. El propósito de los bloqueos livianos es proporcionar un mecanismo de sincronización de baja contención con la premisa de reducir la sobrecarga de la conmutación de subprocesos y la cancelación de bloqueos.

3.1.4, estado de bloqueo pesado

Cuando hay una competencia intensa entre varios subprocesos, la JVM marcará el objeto como un estado de bloqueo pesado. Los bloqueos pesados ​​​​se implementan utilizando el mutex proporcionado por el sistema operativo, lo que implica bloquear y activar subprocesos y requiere la intervención del sistema operativo.

3.2 Condiciones de transición de estado

3.2.1, sin bloqueo -> bloqueo sesgado

  • Cuando un subproceso accede al bloque sincronizado por primera vez, el objeto se marca como bloqueado y registra la identificación del subproceso actual.
  • Condición de transición: otro subproceso accede al objeto en el estado sin bloqueo.

3.2.2, bloqueo sesgado -> sin bloqueo

  • Cuando el objeto está en un estado de bloqueo sesgado, si otro subproceso intenta adquirir el bloqueo, se revocará el bloqueo sesgado.
  • Condición de transición: otro subproceso intenta adquirir un bloqueo sesgado.

3.2.3, bloqueo sesgado -> bloqueo ligero

  • Cuando un subproceso ingresa repetidamente al bloque de código sincronizado, pero hay competencia, el bloqueo sesgado se actualizará a un bloqueo ligero.
  • Condición de transición: hay competencia por bloqueos sesgados en el mismo objeto.

3.2.4, candado ligero -> candado pesado

  • Los candados livianos se actualizan a candados pesados ​​cuando existe una competencia intensa entre varios subprocesos.
  • Condición de transición: Falla la competencia de operación CAS de esclusas livianas.

3.2.5 Cerradura pesada -> Cerradura ligera

  • Cuando un subproceso que contiene un bloqueo de peso pesado libera el bloqueo, el bloqueo intenta degradar a un bloqueo de peso ligero.
  • Condición de transición: el subproceso que sostiene el bloqueo de peso pesado libera el bloqueo.

4. Proceso de actualización de bloqueo

无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁
  1. Actualización de bloqueo sesgado: cuando un subproceso accede a un bloque sincronizado, primero intentará adquirir un bloqueo sesgado. Si el objeto actual no ha sido competido por otros subprocesos, y el subproceso que contiene el bloqueo sesgado aún está vivo, entonces el subproceso actual puede adquirir directamente el bloqueo sesgado sin escalada de bloqueo.
  2. Actualización de candado ligero: si la adquisición de un candado sesgado falla, lo que indica que existe competencia por el objeto actual, el candado sesgado se actualizará a un candado ligero. En este momento, la JVM cambiará la marca de bloqueo en el encabezado del objeto a un puntero al registro de bloqueo (Registro de bloqueo) en la pila de subprocesos a través de la operación CAS y copiará el contenido del objeto al registro de bloqueo.
  3. Actualización de bloqueo giratorio: si falla la adquisición del bloqueo ligero, es decir, varios subprocesos compiten por el bloqueo del mismo objeto, el bloqueo ligero se actualizará a un bloqueo giratorio. El bloqueo de giro no bloquea el subproceso, pero permite que el subproceso realice una espera ocupada, intentando adquirir el bloqueo repetidamente. Esto puede evitar la pérdida de rendimiento causada por el cambio de subprocesos.
  4. Actualización de bloqueo de peso pesado: cuando el número de intentos de bloqueo de giro para adquirir un bloqueo alcanza un cierto umbral, o el tiempo de espera supera un límite determinado, el bloqueo de giro se actualizará a un bloqueo de peso pesado. El bloqueo de peso pesado bloqueará el hilo, pondrá el hilo que compite por el bloqueo en la cola de espera y se despertará después de que se libere el bloqueo.

Diagrama de flujo de actualización general:

El diagrama de flujo específico es el siguiente:

5. ¿Se puede degradar el bloqueo?

En Java, los bloqueos generalmente no se degradan activamente, es decir, una vez que un bloqueo se actualiza a un bloqueo de nivel superior (como la actualización de un bloqueo sesgado a un bloqueo ligero o un bloqueo de peso pesado), no se degradará automáticamente de nuevo a un bloqueo bloqueo de nivel inferior.

Sin embargo, hay un caso en el que la cerradura se degradará, es decir, una cerradura pesada puede degradarse a una cerradura liviana cuando se suelta. Esta degradación se produce después de que el subproceso que sostiene el bloqueo de peso pesado libera el bloqueo. Si la próxima situación de competencia es más suave, es decir, la contención de bloqueo es baja, el sistema intentará degradar el bloqueo de peso pesado a un bloqueo de peso ligero para reducir la sobrecarga cuando subsiguientes subprocesos competir por la cerradura.

La JVM maneja automáticamente el proceso de degradación, y las condiciones y estrategias de activación específicas pueden variar según la implementación de la JVM. En términos generales, cuando el subproceso que libera el bloqueo pesado detecta que ningún otro subproceso compite por el mismo bloqueo, degrada el bloqueo a un bloqueo ligero.

Cabe señalar que la degradación del bloqueo no ocurre en todos los casos, depende de las condiciones de carrera del sistema y la implementación específica de la JVM. En aplicaciones prácticas, no podemos controlar directamente el comportamiento de degradación de los candados, por lo tanto, al seleccionar y usar candados, debemos considerar exhaustivamente de acuerdo con situaciones y necesidades específicas, y sopesar el nivel y el rendimiento de los candados.

 

Supongo que te gusta

Origin blog.csdn.net/p793049488/article/details/131513512
Recomendado
Clasificación