uso sincronizada y simple analítica

uso sincronizada y simple analítica

1. escenarios de uso:

Cuando varios subprocesos al mismo tiempo operan en los mismos recursos críticos, nos encontraremos que el código no está sincronizado, lo que resulta en los resultados puede ser más allá de nuestras expectativas. Por ejemplo, el siguiente ejemplo:


public class Async implements Runnable {
	
	//临界变量
	static int i=0;
	
 public static void increase()
	{
		for(int i=0;i<5;i++)
		{
			System.out.print(i);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		increase();
	}
	
	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		Async async = new Async();
		Async async2 = new Async();
		
		Thread thread1 = new Thread(async);
		Thread thread2 = new Thread(async2);
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();
		//join 表示将当前线程执行完毕后再返回线程
	}
/*
每次运行的结果是随机的
*/

}

La ejecución de este código podemos encontrar no es el mismo resultado cada vez que la ejecución de código. Esto es los hilos de resultados no están sincronizados. Y si queremos llegar a ser la sincronización de código, es necesario cerradura.
El modo de bloqueo es muy sencillo, basta con añadir una palabra clave en el método de aumento (): la sincronización puede ser.
De la siguiente manera:

synchronized public static void increase()
	{
		for(int i=0;i<5;i++)
		{
			System.out.print(i);
		}
	}

2. Clasificación

El caso siguiente se sincronizará se divide en dos categorías. Uno de ellos es el bloqueo del objeto, cerradura, y clase.
Proteger objeto del objeto de bloqueo, la información de cabecera del objeto java marca de la palabra almacena información de campo en la cerradura.

3. Aplicaciones específicas:

sincronizada Hay tres aplicaciones principales:

  • Ejemplos de método modificado, la corriente aplicada a la instancia de bloqueo, antes de entrar un código de sincronización para obtener la instancia actual de la cerradura

  • La modificación de los métodos estáticos, el papel de la corriente de bloqueo objeto de clase, antes de entrar el código de sincronización de bloqueo para obtener la clase de objeto actual

  • Modificación del bloque de código, objeto de bloqueo designado, para bloquear un objeto dado, antes de entrar en la biblioteca de código de sincronización para obtener un bloqueo determinado del objeto.

Ejemplos 3.1 Método aplicado:


public class Async implements Runnable {
	
	//临界变量
	static int n=0;
	
	 public synchronized  void increase()
	{
		for(int i=0;i<5;i++)
		{
			n++;
			System.out.print(n);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		increase();
	}
	

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		Async async = new Async();
		
		Thread thread1 = new Thread(async );
		Thread thread2 = new Thread(async );
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();

	}

	

}

3.2 Modified método estático:

Cuando hay varios objetos en nuestro código para acceder a los mismos recursos estáticos, tenemos que bloquear los recursos estáticos.


public class Async implements Runnable {
	
	//临界变量
	static int n=0;
	
	 public synchronized static void increase()
	{
		for(int i=0;i<5;i++)
		{
			n++;
			System.out.print(n);
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		increase();
	}
	

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		Async async = new Async();
		Async async2 = new Async();
		
		Thread thread1 = new Thread(async );
		Thread thread2 = new Thread(async2 );
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();

	}

	

}

3.3 especificar un código de bloques modificados:

Cuando nuestro método es demasiado grande, pero el bloque de código necesidad de sincronizarse sólo una pequeña parte de las veces, sólo queremos añadir bloqueo de sincronización en el bloque de código sincronizado, de la siguiente manera:


public class Async implements Runnable {
	
	private static Async async = new Async();
	
	//临界变量
	static int n=0;
	

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		synchronized(this)//this指代async 对象
		{
			for(int i=0;i<5;i++)
			{
				n++;
				System.out.print(n);
			}
		}
	}
	

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		
		
		Thread thread1 = new Thread(async);
		Thread thread2 = new Thread(async);
		
	
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();

	}

	

}

Cuando se utiliza el bloqueo de sincronización de bloque, podemos pasar el objeto que desea sincronizar, o un objeto de clase.

Vale la pena mencionar que, cuando el bloqueo síncrono no estático, hilo B llama el bloqueo síncrono no estático cuando un hilo Una llamada que una llamada de bloqueo de objeto, una llamada a la cerradura de la clase cuando los dos bloqueos no son mutuamente excluyentes. En este momento, se producen problemas de hilo de seguridad.

4. sencilla analítica

4.1Monitor

En la JVM, la disposición objeto en la memoria se divide en tres áreas: los primeros objetos, datos de instancia y de relleno de alineación.
En el encabezado del objeto, hay un campo llamado Markdown, este campo es de longitud variable. Que almacena la información objeto hashCode cerradura o la edad o signos GC generacionales y otra información. cerraduras de peso pesado almacenados en los puntos de información a un monitor objeto (objeto Monitor). java cada objeto tiene un objeto de monitor correspondiente. Cuando el monitor se lleva a cabo de un hilo, el objeto estará en un estado bloqueado.

Java Virtual Machine (HotSpot) en, ObjectMonitor monitor se implementa, la estructura principal de datos es el siguiente (en los archivos de origen HotSpot VM ObjectMonitor.hpp, implementación en C ++)

ObjectMonitor hay dos colas, _WaitSet y _EntryList, para ahorrar lista de objetos ObjectWaiter (cada hilo esperará a que el bloqueo a embalar objetos ObjectWaiter), _ propietario hilo sostiene ObjectMonitor punto objeto, cuando una pluralidad de hilos de acceder simultáneamente a la período de sincronización cuando el código, introduzca primer conjunto _EntryList, cuando el hilo entra en el objeto de monitor adquirido _Owner área del monitor y el propietario es el hilo actual, mientras que la variable se establece para controlar el recuento del contador se incrementa en 1 si la espera hilo llamando al método (), la liberación Actualmente cabo monitor, la recuperación variable de propietario es nulo, contar desde menos 1, mientras que el hilo entra WaitSe t conjunto espera de ser despertado. Si el hilo terminado la actual liberará el monitor (bloqueo) y se restablece el valor de la variable, de modo que otros hilos consiguen en el monitor (bloqueo). Como se muestra en la figura.

Aquí Insertar imagen Descripción

4.2 Método de bloqueo:

El método de la etapa de sincronización implícita, es decir, sin controlado por las instrucciones de código de bytes que implementa la llamada al método y el retorno en la operación. JVM si un método puede ser distinguido del método de sincronización del método del método ACC_SYNCHRONIZED estructura de la tabla de la piscina constante de banderas de acceso (estructura) de method_info. Cuando se llama al método, la instrucción de llamada comprobará si se establece el método de la bandera de acceso ACC_SYNCHRONIZED, si conjunto, hilo de ejecución será primera monitor de retención (usando la especificación de máquina virtual término es el tubo), a continuación, realizar el método, y finalmente otra forma de lograr (tanto normal y no normal finalización o terminación) del monitor liberación en el tiempo. Durante la ejecución del método, hilo de ejecución tiene el monitor, ningún otro hilo ya no puede obtener el mismo monitor. Si un método de sincronización se produce una excepción durante la ejecución, y no puede manejar esta excepción dentro de la forma, que este método de sincronización en poder del monitor se activa automáticamente cuando una excepción arrojada fuera del método de sincronización.

5.Java optimización de la máquina virtual sincronizado

Hay cuatro estado de la cerradura, sin estado de bloqueo, tienden a bloqueo, ligero y cerradura de bloqueo de peso pesado. Con el bloqueo de la competición, puede actualizar de tope a tope sesgada por bloqueo ligero, a continuación, actualizar bloqueo de peso pesado, pero la extensión de bloqueo es unidireccional, es decir actualización sólo de abajo hacia arriba, no aparecerá la cerradura rebajar.

5.1 bloqueo sesgada

Sesgado bloqueo del principal escenario de referencia es: En algunos casos, un bloqueo de la mayor parte del tiempo no competirá múltiples hilos simultáneamente, pero con frecuencia se llevó a cabo en varias ocasiones por el mismo hilo. Sesgado idea núcleo de bloqueo es que si un hilo se pone la cerradura, entonces la cerradura para entrar en el modo de polarización, donde también la estructura Marcos palabra se convierte sesgada estructura de bloqueo, cuando el hilo de nuevo solicitando un bloqueo, y no más allá de sincronización, a saber, el proceso de adquisición de la cerradura, eliminando así un gran número de operaciones relativas a la aplicación de esclusas, que proporcionará el rendimiento del programa. Pero cuando un recurso a menudo se adelantó varios subprocesos cuando está polarizado no bloqueo para usted. Tras el fracaso de bloqueo sesgada, y no se expandirá bloqueo inmediato de peso pesado, pero la primera actualización de bloqueo ligero.

5.2 Bloqueo Ligera

Si tienden a no bloqueo, la máquina virtual no va a actualizar de inmediato a la cerradura de peso pesado, que tratará de optimizar el uso de una herramienta llamada un bloqueo ligero (después de añadir 1,6), entonces la estructura de marca de la palabra también se convierte en luz el orden de la estructura de bloqueo. Sobre la base de una cerradura de peso ligero puede mejorar el rendimiento del programa es "a la mayoría de las cerraduras, no hay competencia en todo el ciclo de sincronización," Tenga en cuenta que estos son los datos empíricos. Necesidad de entender que el bloqueo de peso ligero de la adaptación de la escena se realiza bloque de sincronización ocasión hilo alternativamente, si hay un bloqueo para acceder a la misma ocasión al mismo tiempo, que dará lugar a la inflación de bloqueo bloqueo de peso ligero.

5.3 Los spinlocks

Después de que falle una cerradura de peso ligero, la máquina virtual con el fin de evitar los bloqueos de rosca real en el nivel de sistema operativo, sino también un medio para optimizar conocido como bloqueo de giro. Este estado es la necesidad de convertir de usuario basada, en la mayoría de los casos, el hilo que mantiene el tiempo de bloqueo no será demasiado largo, si están directamente colgados del hilo a nivel de sistema operativo puede ser desperdiciado, después de todo, el sistema operativo para cambiar entre los hilos transiciones básicas de estado entre el estado requiere un período relativamente largo de tiempo, el costo de tiempo es relativamente alta, por lo que el bloqueo de bucle asumirá en el futuro cercano, el subproceso actual puede adquirir el bloqueo, por lo que las oportunidades para las discusiones virtuales que se encuentran actualmente quieren obtener un bloqueo hacer un par de ciclo de vacío (que también se conoce como el giro razones), por lo general no es demasiado largo, puede ser de 50 ciclos o 100 ciclos, después de varios ciclos, si se obtiene un bloqueo, entran con éxito la región crítica. Si no puede obtener el bloqueo, que será el hilo se bloquea nivel del sistema operativo, esta es la manera de optimizar el bloqueo de giro, de hecho, de esta manera se puede mejorar la eficiencia. Por último, no hay manera que sólo se puede actualizar a peso pesado bloqueado.

5.4 Bloqueo de eliminación

La eliminación de la cerradura es otra optimización de bloqueo de máquina virtual, esta optimización es más completo, Java tiempo de compilación de la máquina virtual JIT (puede ser entendido como un simple trozo de código que se compila cuando a punto de ser ejecutado por primera vez, también conocida como la compilación en tiempo real), mediante el escaneo de funcionamiento de la cerradura contexto, no puede haber ninguna eliminación de la competencia por los recursos compartidos, eliminando de esta manera el bloqueo no es necesario, se puede ahorrar tiempo las solicitudes de bloqueo sin sentido, como append de StringBuffer un método de sincronización, además de añadir en el camino StringBuffer pertenecen a una variable local, y no será usado por otros hilos, por lo que no puede haber una escena StringBuffer contención de recursos compartidos, JVM automáticamente se bloqueará eliminado.

6.synchronized puntos clave:

6.1

sincronizada es reentrante, lo que significa Cuando un hilo mantiene el bloqueo, de nuevo, cuando se solicite, no se bloquearán.

6.2

Cuando un hilo interrupciones, el método de interrupción llamando ejemplo hilo de un objeto que bloquea la interrupción anormal y lanza excepciones InterruptedException, el estado de interrupción también se restablecerá. Así que por un hilo, si cuando se produce la interrupción, se está a la espera para una cerradura que va a seguir esperando a la cerradura. Si se ha obtenido un bloqueo, continuará. Así que cuando llamamos interrupción método (), debe detectar de forma manual si el hilo se interrumpe, y luego hacer el tratamiento adecuado.

6.3

Cuando el hilo se despierta, despertando la declaración debe ser sincronizado bloque o método sincronizado, de lo contrario se producirá una excepción IllegalMonitorStateException Esto es debido a que estos métodos se debe llamar antes para conseguir el objeto de destino monitor de monitor de corriente, es decir notifiquen / notifyAll y métodos de espera dependen de los objetos de monitor
y diferentes métodos de sueño es de esperar después de que se complete la llamada al método, el hilo será suspendido, pero el método de espera liberará el bloqueo actual en poder del monitor (monitor), hasta que las llamadas de rosca notifiquen / después notifyAll método sólo puede continuar, pero sólo el hilo con el método del sueño del sueño no libera el bloqueo. Mientras que la parte trasera notificar llamadas / notifyAll método, y no libera inmediatamente el monitor de bloqueo, pero () {} / método sincronizado se realiza automáticamente liberar el bloqueo solamente después del final de la respectiva sincronizada.

En la presente memoria por referencia: [https://blog.csdn.net/javazejian/article/details/72828483?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task]

Publicado 47 artículos originales · elogios ganado 15 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/qq_41525021/article/details/104596262
Recomendado
Clasificación