Hacia el oeste sincronizada y la extensión de bloqueo

prefacio

socio menor Hola a todos, soy un gato Xu, hoy es las vacaciones de Ching Ming, para charlar con sincronización realizada. Benpian es la primera programación concurrente, y por qué es el primero, porque demasiadas cosas que intervienen en la programación concurrente, oscurecen, acaba de sacar un conocimiento puede escribir un artículo, tal cálculo terminar una serie de programación concurrente al menos a diez. Voy a resumir los puntos de conocimiento, categoría de clasificación clasificado, con una forma fácil de usar que le diga que está claro, hablo de entender. .

¿Por sincronizada

Este problema es muy sencillo, primer vistazo a los siguientes códigos

10000 hilo abierto, el recuento variable se incrementa, el resultado es 9998, está claro que hay una caja fuerte hilo. ¿Por qué hay tal resultado, la respuesta es simple

这里稍微解释下为啥会得不到 100(知道的可直接跳过), i++ 这个操作,计算机需要分成三步来执行。
1、读取 i 的值。
2、把 i 加 1.
3、把 最终 i 的结果写入内存之中。
所以,(1)、假如线程 A 读取了 i 的值为 i = 0,(2)、这个时候线程 B 也读取了 i 的值 i = 0。
(3)、接着 A把 i 加 1,然后写入内存,此时 i = 1。(4)、紧接着,B也把 i 加 1,此时线程B中的 i = 1,
然后线程B 把 i 写入内存,此时内存中的 i = 1。也就是说,线程 A, B 都对 i 进行了自增,但最终的结果却是1,不是 2.
复制代码

En última instancia frase no es tanto la atomicidad de la operación, a continuación, la forma de resolver este problema, puede agregar sincronizada

tres características

En el ejemplo anterior demostrado que atómica. sincronizada para asegurar la visibilidad, de acuerdo con un predeterminado sucede-antes de, después de un hilo de ejecución del código sincronizado, todos los cambios de código a las variables inmediatamente pueden ser vistos por otros hilos. El orden de las palabras está prohibido reordenamiento de instrucciones, código de bloque de la ejecución de código abajo secuencialmente desde el último análisis, a continuación, una palabra, tres características sincronizadas problemas de concurrencia está garantizada, que se sincroniza es el aceite de serpiente, asegúrese de usar su !

uso

Gramaticalmente hablando, el total sincronizado de tres usos:

  • Ejemplos de método modificado
public synchronized void eat(){
	.......
  .......
}
复制代码
  • método estático Modificado
public static synchronized void eat(){
	.......
  .......
}
复制代码
  • bloque modificado
public void eat(){
   synchronized(this){
   	.......
 	.......
   }
}
复制代码
public void eat(){
   synchronized(Eat.class){
   	.......
 	.......
   }
}
复制代码

En el que la primera y la tercera en el otro, el segundo y el cuarto y así sucesivamente, esto es muy simple, aquí es un resumen del uso de sincronizada:

  • La selección de un objeto de bloqueo puede ser cualquier objeto;
  • El objeto de bloqueo está bloqueado bloque sincronizado, no su propia;
  • Los diferentes tipos de código de sincronización de rosca múltiple para ser ejecutados si el objeto de bloqueo a utilizar todos los hilos que sostienen juntos el mismo objeto;
  • Necesidad de código de sincronización entre llaves. Medios que deben sincronizarse para garantizar la atomicidad requiere, la visibilidad, el orden de uno o más. No ponga ninguna sincronización de código en, influir en la eficiencia del código.

la extensión de bloqueo

Bueno, el punto culminante de este vino, escuchamos con atención, llamado bloqueo de peso pesado a principios de JDK, sincronizado, debido a que los recursos de la aplicación de bloqueo deben ser llamados por el núcleo, el sistema, de modo de usuario -> eficiencia de conversión de modo de núcleo es relativamente baja, JDK1. después de hacer algunas optimización 6, con el fin de reducir para obtener y cerraduras de liberación ofrecer un rendimiento sobrecarga introducida bloqueo sesgo, el concepto de bloqueo de peso ligero. Por lo que encontrará en sincronizada, los cuatro estados están enganchadas: sin bloqueo, tienden a bloqueo, ligero bloqueo, bloqueo de peso pesado;

Sabemos sincronizados objeto de bloqueo, el objeto es el objeto, el diseño de objetos en el montón, como se muestra en la figura.

Frente a un tamaño específico es de 8 bytes markword, los siguientes cuatro bytes son el puntero de la clase es el objeto pertenece a qué clase, la gente es People.class, categoría Gato es Cat.class, después de que los datos de instancia de clase que hay que ver que el campo a, int edad es de 4 bytes, el nombre de la cadena es un byte Inglés, 2 bytes conjunto chino (el número de bytes depende del uso de la cadena china de codificar un tipo UTF-8, los chinos representaron 2 a 3 bytes, si el tipo de GBK, los chinos 2 bytes), y finalmente la parte delantera tres combinados no divisible por 8, se rellena a ser divisible por 8. Perfil es markword (8 * 8 = 64 bits) en la figura, dentro de la extensión de bloqueo es el cambio de la bandera de reducción del precio.

Por lo tanto, mapa en línea son de 32 bits, aquí me saco es de 64 bits, encontramos un total de cinco estados, con dos no es suficiente, por lo que cuando la 01 hacia adelante por uno.

bloqueo sesgada

En la máquina virtual punto de acceso después de una investigación encontró que, en la mayoría de los casos, no hay código de bloqueo no es sólo la competencia multi-roscado, y siempre obtener el mismo hilo varias veces. Así que basado en una probabilidad, empezamos el bloqueo de la cerradura está sesgada, cuando un acceso de bloqueo de sincronización de hilos, más un bloque de código, primero intentarán almacenar el hilo actual en la cabeza por un objeto ID de operación del CAS

(1) Si el hilo actual se almacena con éxito markword ID, a continuación, hacer bloque de sincronización

(2) Si el mismo hilo cuando bloqueado, sin contención, indicador de paso simplemente determina si la misma se puede realizar directamente bloque sincronizado

(3) Si hay otros hilos de bloqueo ha ganado el favor, este caso demuestra que el bloqueo actual hay competencia, es necesario deshacer el mensaje ha sido sesgada de bloqueo, y para actualizar los bloqueos mantenidos como un bloqueo ligero (esta operación tiene que esperar hasta mundial punto de seguridad, es decir, no hay hilos en la ejecución de código de bytes) para realizar

En nuestro desarrollo de aplicaciones, sin duda habrá más de dos hilos compiten en la mayoría de los casos, si usted tiende a abrir la cerradura, que mejorará el acceso a la cerradura de agotamiento de los recursos. Por lo tanto, los parámetros pueden ser establecidos por JVM UseBiasedLocking sesgada de bloqueo en o fuera

cerradura de peso ligero

Revocación de bloqueo, bloqueo de peso ligero ascenso sesgada, cada hilo en su propia pila de subprocesos genera LockRecord, con la operación CAS markword conjunto para que señale el propio hilo LR, se proporciona una cerradura para dar éxito. Ligera bloqueado en el proceso de bloqueo, el uso de bloqueos de giro, el uso de bloqueos de giro, de hecho, hay ciertas condiciones, si un subproceso en ejecución bloque de tiempo sincronizado es muy larga, a continuación, el hilo continúa ciclo pero consumirá recursos de la CPU.

Número (1) por giro predeterminado es de 10 veces, puede -XX: modificar PreBlockSpin, o número de hilos de giro de más de la mitad el número de núcleos de CPU

(2) Después de jdk1.6, la introducción de bloqueo de giro adaptativa, medios de adaptación que el número de giro no es fijo, pero al mismo tiempo de acuerdo a un tiempo antes de que el bloqueo de giro y el propietario de bloqueo el estado para decidir. Si un bloqueo en el mismo objeto spin-espera sólo cerraduras ganado con éxito, y el hilo de la celebración de la cerradura está en funcionamiento, la máquina virtual va a pensar que este giro es probable que tenga éxito una vez más, y luego se permitirá giro esperar un tiempo relativamente más largo. Si por una cerradura, giro rara vez ha tenido éxito, que al intentar adquirir el bloqueo será posible omitir el proceso de escisión, bloqueando directamente el procesador hilo para evitar el desperdicio de recursos en el futuro

Después de cualquiera de estos dos casos actualizado a la cerradura de peso pesado

cerradura de peso pesado

Esta vez a molestar Lafayette, y aplicar recursos para el sistema operativo, Linux mutex, llamadas de CPU de sistema de nivel de grado 3-0, suspensión hilo, en la cola de espera, esperando a que el programador del sistema operativo, y luego se asigna de nuevo al espacio de usuario.

Sólo escribimos un código simple con la palabra clave sincronizada. En primer compilado en archivos .class, y luego usar javap -c xxx.class desmontar. Podemos obtener el código correspondiente a la Java instrucción ensamblador. Que se pueden encontrar los siguientes dos líneas de instrucciones.

Bytecode instrucciones de dos dimensiones es fundamental, MonitorEnter, moniterexit (Nota: el uso de un bloque de código ACC_SYNCHRONIZED, este es un bit de signo, el principio subyacente o dos instrucciones)

java cada objeto está asociado con un monitor de bloqueo del monitor, cuando el monitor está en un estado bloqueado va a ocupar. Subproceso intenta adquirir la propiedad del monitor al ejecutar la instrucción MonitorEnter, de la siguiente manera:

  • Si el número de entrar en el monitor es 0, el hilo entra en el monitor, y a continuación, introduzca el número se establece en 1, el hilo es el propietario del monitor.
  • Si el hilo ha ocupado el monitor, sólo para volver a entrar, a continuación, introduzca el número en el monitor más uno.
  • Si otro hilo ha ocupado el monitor, el hilo entra en el estado bloqueado en el monitor hasta que el número es cero, entonces re-intento de obtener la propiedad del monitor.

Como puede verse a partir de los dos procesos anteriores, la primera: Monitor es reentrante, él contadores, segundo: Monitor de bloqueo no justo

supervisar mutexLock depende del sistema operativo (mutex) para conseguir, después de introducir el hilo del núcleo está bloqueado (Linux) estado de programación, esto hará que el sistema para volver interruptor y vuelta entre el modo de usuario y modo de núcleo, afectar seriamente el rendimiento de la cerradura

eliminación de bloqueo

Todos sabemos que StringBuffer es seguro para subprocesos, porque es métodos críticos son modificados para ser sincronizado, pero nos fijamos en el código anterior, nos encontraremos, sb Esta referencia sólo será utilizada en el método add, otros hilos no pueden ser referencia (porque es variables locales, apilar privado), sb tanto, es imposible compartir recursos, JVM se bloquea automáticamente la eliminación del objeto interno StringBuffer.

public void add(String str1,String str2){
         StringBuffer sb = new StringBuffer();
         sb.append(str1).append(str2);
}
复制代码

resumen

Los buenos puntos de conocimiento comprendidas en este artículo se han sincronizado para explicar con mucha claridad. programación concurrente de Java sincronizada es la forma más común de garantizar flujos seguros, su uso también es relativamente simple. Antes sincronizado para optimizar el rendimiento de la sincronizada de ReentrantLock mucho, pero desde la introducción de bloqueo sesgada sincronizado, después de que el bloqueo de peso ligero (bloqueos de giro), la diferencia de rendimiento entre los dos es casi lo mismo. En el caso de los dos métodos están disponibles, el uso de oficial sincronizada incluso sugirió, de hecho, me siento sincronizado prestadas técnicas de optimización CAS ReentrantLock en. Ellos están tratando de poner en modo de usuario de bloqueo resolver problemas e hilo evitar el bloqueo en el modo de núcleo.

Supongo que te gusta

Origin juejin.im/post/5e898b8fe51d4546cd2fda30
Recomendado
Clasificación