Multihilo combate de sintonía

Resumen: En un programa concurrente, no el inicio puede hacer el programa más hilos para maximizar la ejecución concurrente. El número de hilos es demasiado pequeño, hará que el programa para no utilizar plenamente los recursos del sistema; el número de hilos demasiado grande, puede llevar a una excesiva competencia por los recursos, lo que resulta en un contexto adicional de conmutación por encima. Este artículo analiza los problemas de rendimiento en multi-hilo contexto de conmutación. Referencia: Liu Chao de "combate de Java Performance Tuning"

1. interruptores qué contexto?

Concepto: Cuando segmento de tiempo de un hilo se acaba, o forzado a suspender el funcionamiento por sus propias razones, y esta vez, otro hilo (el hilo puede ser el mismo hilo u otro proceso) será seleccionado por el sistema operativo para ocupar procesador .Tal hilo se suspende privado del derecho a utilizar otro hilo se selecciona para iniciar o continuar para ejecutar el proceso se llama contexto de conmutación (cambio de contexto).

conceptos relacionados detalle
"Corte" Un hilo se ve privado del derecho a utilizar el procesador de operación ha sido suspendido
"Cut" Un hilo es seleccionado para iniciar o continuar ejecutando intensivo del procesador
"Contexto" En este proceso de corte a cabo el corte, la necesidad de guardar y restaurar el sistema operativo correspondiente información de la programación, la información de programación es "contexto" a, ( que incluye un registro de instrucciones, los contenidos almacenados en los contenidos almacenados en el contador de programa )

2, multi-hilo razón el cambio de contexto?

Ciclo de vida de las hebras Java 2.1 estatales

Aquí Insertar imagen Descripción
El hilo conductor de "nueva" (NUEVO), "Ready" (RUNNABLE), "Run" (MARCHA), "bloqueo" (BLOQUEADO), "la muerte" (DEAD) cinco estados.Subproceso de proceso no RUNNABLE se gira por el RUNNABLE cambio de contexto hilo

  • BLOQUEADO estado Hilo de correr o convertido en un RUNNABLE bloqueada, esto es lo que lo indujo?
razón detalle
Uno de ellos es el programa de interruptor de disparo en sí, lo que llamamos cambio de contexto espontánea contexto del subproceso espontánea significa que los programas Java llamados por el plomo cortan conmutación . En la programación multi-roscado, llamando a los métodos o las palabras clave siguientes, a menudo dará lugar a cambios de contexto espontánea. sleep (), wait (), rendimiento (), join (), parque (), sincronizada, bloqueo
Otro contexto es no espontáneo o inducido por el sistema de conmutación de máquina virtual Se refiere a la conmutación de contexto hilo involuntaria debido a la necesidad de estar fuera del planificador . Comunes son: intervalo de tiempo que un hilo está asignado se agota, la causa de recolección de basura máquina virtual o el plomo a la aplicación de las cuestiones prioritarias
  • ¿Por qué la recolección de basura máquina virtual puede provocar un cambio de contexto?

En lo virtual objeto de memoria de la máquina Java es, el programa se está ejecutando, el nuevo objeto seguirá siendo creado por la asignación máquina de pila virtual, si no se recupera después de que el antiguo objeto utiliza la memoria del montón será pronto agotado.Máquina Virtual de Java proporciona un mecanismo de recogida, después de crear objetos ya no se utilizan para el reciclaje, con el fin de asegurar la sostenibilidad de la pila de memoria asignada. El uso de este mecanismo de recolección de basura es probable que conduzca a la fuente de stop-el-mundo, que es en realidad un comportamiento hilo suspendido.

Qué aspectos 2.2 específico, gastos generales se produce en el proceso de traspaso

  1. el sistema operativo para guardar y restaurar contexto;
  2. Un planificador para hilos de programación;
  3. Procesador de recarga caché;
  4. El cambio de contexto también puede conducir a toda el área de caché se vacía, lo que lleva a los gastos generales tiempo.

3, Resumen

El cambio de contexto hilo es una obra de otro hilo se suspende, el proceso toma hasta otro procesador hilo comienza a ejecutar tareas. los programas del sistema y Java espontáneas y operación de recuperación espontánea, no dará lugar a cambio de contexto, lo que lleva a la sobrecarga del sistema.

  • Los más hilos, la velocidad del sistema no es necesariamente más rápido. Por lo tanto, generalmente más grandes que las circunstancias concurrentes, cuándo usar un único subproceso, multi-hilo cuándo usarlo?

    En general, una sola lógica es relativamente simple, y la velocidad relativa a la muy rápida, podemos usar el single-roscado. Por ejemplo, hemos hablado de la Redis, los valores de la memoria de lectura rápida, sin tener en cuenta problemas de bloqueo de E / S cuello de botella causado.En la lógica es relativamente escenas muy complejas, espera por un tiempo relativamente largo, o es que requiere una gran cantidad de cálculo de la escena, le recomiendo usar multihilo para mejorar el rendimiento general del sistema. Por ejemplo, las operaciones, procesamiento y análisis de datos grandes archivos de imágenes periodo de escritura NIO.

4, la forma de optimizar el cambio de contexto multi-hilo?

  • Es el uso de la programación multi-threading en algunos escenarios muy necesarias, pero multi-roscado al sistema trajo un cambio de contexto, lo que aumenta el rendimiento de sobrecarga es existía el verdadero negocio. Entonces, ¿cómo optimizar contexto multi-hilo de ponerlo?

4.1 Bloqueo de la competencia optimización

método detalle
1. Reducir el tiempo de retención de bloqueo Algunos de bloque de sincronismo de bloqueo de código independiente se puede eliminar, en particular los de gran sobrecarga pueden ser bloqueados y el funcionamiento de la operación
2. Reducir la granularidad de bloqueo Considere dividir la granularidad de bloqueo numérico más pequeño, con el fin de evitar todos los hilos de una competencia por los recursos de bloqueo es demasiado fuerte. Hay dos maneras específicas: bloqueo separado (bloqueo bloqueos de escritura para la separación, no exclusivo de lectura) y el segmento de bloqueo (Java1.8 versiones anteriores del segmento de bloqueo en el uso ConcurrentHashMap)
3. Sin bloqueo bloqueo optimista contención de bloqueo de reemplazo CAS es un algoritmo libre de bloqueo para asegurar la consistencia de una variable compartida leer y operaciones de escritura. En jdk1.6, JVM se bloqueará en una cerradura sesgada sincronizado síncrono, ligero bloqueo, bloqueo de peso pesado y sesgada de bloqueo, el camino óptimo se realiza en el orden anterior. Compilador JIT al compilar bloques de sincronización dinámica, también mediante la eliminación de la cerradura, la cerradura engrosamiento manera de optimizar el bloqueo de sincronización

4.2 de espera / notificar a la optimización

Objeto del objeto puede ser llamado por método de mezcla wait (), y notificar () método método o notifyAll () para lograr la comunicación entre hilos.

  • Vamos a implementar un simple caso de los productores y consumidores a través de la espera () / notify ()
public class WaitNotifyTest {
    public static void main(String[] args) {
        Vector<Integer> pool=new Vector<Integer>();
        Producer producer=new Producer(pool, 10);
        Consumer consumer=new Consumer(pool);
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}
	/**
	 * 生产者
	 * @author admin
	 */
	class Producer implements Runnable{
	    private Vector<Integer> pool;
	    private Integer size;
	    
	    public Producer(Vector<Integer>  pool, Integer size) {
	        this.pool = pool;
	        this.size = size;
	    }
	    public void run() {
	        for(;;){
	            try {
	                System.out.println(" 生产一个商品 ");
	                produce(1);
	            } catch (InterruptedException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            }
	        }
	    }
	    private void produce(int i) throws InterruptedException{
	        while(pool.size()==size){
	            synchronized (pool) {
	                System.out.println(" 生产者等待消费者消费商品, 当前商品数量为 "+pool.size());
	                pool.wait();// 等待消费者消费
	            }
	        }
	        synchronized (pool) {
	            pool.add(i);
	            pool.notifyAll();// 生产成功,通知消费者消费
	        }
	    }
	}
	/**
	 * 消费者
	 * @author admin
	 */
	class Consumer implements Runnable{
	    private Vector<Integer>  pool;
	    public Consumer(Vector<Integer>  pool) {
	        this.pool = pool;
	    }
	    public void run() {
	        for(;;){
	            try {
	                System.out.println(" 消费一个商品 ");
	                consume();
	            } catch (InterruptedException e) {
	                // TODO Auto-generated catch block
	                e.printStackTrace();
	            }
	        }
	    }
	    
	    private void consume() throws InterruptedException{
	        while(pool.isEmpty()){
	            synchronized (pool) {
	                System.out.println(" 消费者等待生产者生产商品, 当前商品数量为 "+pool.size());
	                pool.wait();// 等待生产者生产商品
	            }
	        }
	        synchronized (pool) {
	            pool.remove(0);
	            pool.notifyAll();// 通知生产者生产商品
	            
	        }
	    }
}

Uso de espera / notificar los resultados en más cambios de contexto
Aquí Insertar imagen Descripción

  • En diversos escenarios de consumo,Se puede utilizar el Object.notify () Como alternativa, el Object.notifyAll (). Debido Object.notify () se despertará hilo especificado, no se despierta prematuramente otras necesidades no satisfechas de bloqueo de roscas, es posible reducir el cambio de contexto correspondiente.
  • Después de ejecutar el productor Object.notify () / notifyAll () despertar otros hilos, debe liberar los bloqueos internos tan pronto como sea posible, a fin de evitar otro hilo ejerce en las operaciones comerciales mango de bloqueo largos después de la estela, Para evitar ser aplicación hilo despierta bloqueo interno correspondiente de nuevo cuando la espera de la liberación de bloqueo.
  • Por último, con el fin de evitar largas esperas, a menudo utilizamos Object.wait (largo) establece el tiempo de espera de espera, pero el hilo no puede distinguir su retorno se debe al tiempo de espera o en espera de ser notificado hilo se despierta, lo que resulta en unos intentos de rosca para adquirir la operación de bloqueo otra vez, añadiendo contexto cambiar. (Lock recomienda las interfaces de unión alternativos sincronizados Condición de espera de bloqueo en el interior / notificar, aplicar una espera / notificación)

4.3 razonable para establecer el tamaño del grupo de subprocesos para no crear demasiadas hebras

Establecer el número de procesos en el grupo de subprocesos no es demasiado grandeDebido a que el número de procesadores vez los subprocesos de trabajo del grupo de subprocesos que el número total de sistemas que, se dará lugar a cambios de contexto excesiva

De alguna manera para crear un grupo de subprocesos, el número de hilos de ajuste no está expuesto directamente a nosotros. Por ejemplo, con Executors.newCachedThreadPool () para crear un grupo de subprocesos, la agrupación de hebras para manejar la tarea del nuevo complejo será presentado por su hilo vacío interno, si no, a continuación, crear un nuevo hilo (no restricciones MAX_VALUE), este grupo de subprocesos Si te encuentras con un montón de tareas y escenarios que requieren mucho tiempo, se creará una gran cantidad de subprocesos de trabajo, dando lugar a frecuentes cambios de contexto ( sólo es adecuado para el manejo de un gran número de cortos, de no bloqueo y la tarea que consume tiempo )

4.4 Uso de no bloqueo corrutinas de espera

  • Corrutina es un más ligero que lo que el hilo, en comparación con el núcleo del sistema operativo para gestionar los procesos y subprocesos,Coroutine está completamente controlado por el propio programa, Que se ejecuta en modo de usuario. cambio de contexto Coroutine se evita que el hilo que ha generado el traspaso, se ha mejorado mucho en términos de rendimiento

4,5 reducir la recolección de basura Java Virtual Machine

  • Muchos colector de basura JVM (colector serie, ParNew colector) en el reciclaje de objetos antiguos, se producirá la fragmentación de memoria, por lo tanto la necesidad de consolidación de la memoria, en el proceso que necesita para mover el objeto vivo. Los medios de movimiento que la dirección de memoria objeto de memoria donde estos objetos va a cambiar, por lo que las necesidades de objetos para hacer una pausa antes de hilos en movimiento, después de que el movimiento se ha completado necesidad de despertar el hilo de nuevo .JVM reduciendo así la frecuencia de la recogida de basura se puede reducir de manera efectiva el cambio de contexto

Complementarias : Las preguntas 1: Bloqueo en el JDK, o AQS, el hilo de "colgar" Esta acción es la forma de lograrlo? ¿Por qué no tener un nivel de proceso de cambio de contexto es?

AQS está suspendido por LockSupport el parque en el estado bloqueado, este proceso es que no hay proceso de cambio de contexto. Pero fue bloqueada hilo para adquirir el bloqueo de nuevo, sin cambio de contexto del proceso, y el hilo bloqueado sincronizada adquiere el bloqueo de todos los recursos debe hacerse a través de un sistema llamado el núcleo, por lo tanto consumen más recursos del sistema que AQS bloqueado hilo

Publicado 26 artículos originales · alabanza ganado 18 · vistas 9736

Supongo que te gusta

Origin blog.csdn.net/qq_28959087/article/details/102169680
Recomendado
Clasificación