1. Introducción
El uso racional de grupos de subprocesos puede traer tres beneficios. Primero: reducir el consumo de recursos. Reduzca el consumo causado por la creación y destrucción de los hilos al reutilizar hilos creados. Segundo: mejorar la velocidad de respuesta. Cuando llega una tarea, la tarea se puede ejecutar inmediatamente después de crear el hilo. Tercero: mejorar la capacidad de administración de hilos. Los hilos son recursos escasos. Si se crean ilimitados, no solo consumirán recursos del sistema, sino que también reducirán la estabilidad del sistema. El uso de piscinas de subprocesos puede ser asignación, ajuste y monitoreo unificados. Sin embargo, para hacer el uso racional de las piscinas de hilos, debe conocer bien sus principios.
2. Uso de la piscina de hilos
Los cuatro tipos de hilos proporcionados por los ejecutores 1.NewCachedThreadPool crea un grupo de hilos almacenables. Si la longitud de la piscina de rosca excede las necesidades de procesamiento, puede reciclar de manera flexible hilos inactivos. Si no hay reciclaje, cree un nuevo hilo. 2.NewfixedThreadPool crea un grupo de subprocesos de longitud fija que puede controlar el número máximo de concurrencia de subprocesos, y los hilos excesivos esperarán en la cola. 3.NewScheduledThreadPool crea un grupo de subprocesos de longitud fija que admite la ejecución de tareas cronometradas y periódicas. 4.NewsingLethreadExecutor crea un grupo de subprocesos de un solo hilo, que solo usará un hilo de trabajador único para ejecutar tareas, asegurando que todas las tareas se ejecuten en el orden especificado (FIFO, LIFO, prioridad).
1.NewCachedThreadPool crea una piscina de hilos almacenables. Si la longitud de la piscina de rosca excede las necesidades de procesamiento, puede reciclar de manera flexible hilos inactivos. Si no hay reciclaje, cree un nuevo hilo. El ejemplo es el siguiente
EjecutorService EjecutorService = Ejecutors.NewCachedThreadPool (); para (int i = 0; i <5; i ++) {final int index = i; intente {Thread.sleep (índice * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } EjecutorService.ExeCute (new runnable () {@Override public void run () {system.out.println (thread.currentThread (). getName () + "," + index);}});} // Información de la consola Pool-1-Thread-1,0pool-1-THEAD-1,1POOL-1-THEAT-1,2POOL-1-THEAD-1,3POOL-1-THREAD-1,42.NewfixedThreadPool crea un grupo de subprocesos de longitud fija que puede controlar el número máximo de concurrencia de subprocesos, y los hilos excesivos esperarán en la cola. El ejemplo es el siguiente
EjecutorService fiedThreadPool = ejecutors.newFixedThreadPool (4); for (int i = 0; i <5; i ++) {final int index = i; fijoThreadPool.ExeCute (new runnable () {@Override public void run () {try {System.out.println (Thread.CurrentThread (). Pool-1-Thread-1,0Pool-1-THREAD-2,1POOL-1-THREAD-3,2POOL-1-THEAD-4,3POOL-1-THEAD-1,43.NewscheduledThreadPool Cree un grupo de subprocesos de longitud fija, y los ejemplos de ciclos de soporte y tareas de tiempo son los siguientes
ProgramedExecutorService ProchuledThreadPool = Ejecutors.NeWSChedulEdThreadPool (5); System.out.println ("antes:" + System.CurrentTimemillis ()/1000); ProchuledThreadPool.schedule (new runnable () {@Override public void run () {System.out.println ("Ejecución tardía durante 3 segundos:" + System.CurrentTimemillis ()/1000);}}, 3, TimeUnit.Seconds); System.Println ("After:" +System.CurrentTimemillis ()/1000); // Información de la consola antes: 1518012703After: 1518012703 retrasado durante 3 segundos: 1518012706system.out.println ("antes:" +System.CurentTimemillis ()/1000); programado {@Override public void run () {System.out.println ("Después del retraso de 1 segundo, ejecute una vez en 3 segundos:" +System.CurrentTimemillis ()/1000)Mensaje de la consola
Antes: 1518013024
Después de: 1518013024
Después de 1 segundo retraso, ejecute una vez en 3 segundos: 1518013025
Después de 1 segundo retraso, ejecute una vez en 3 segundos: 1518013028
Después de 1 segundo retraso, ejecute una vez en 3 segundos: 1518013031
4.NewsingLethreadExecutor crea un grupo de subprocesos único, que solo usa hilos de trabajadores para ejecutar tareas, asegurando el orden. El ejemplo es el siguiente
EjecutorService SinglethreadExecutor = Ejecutors.NeWSingLethreadExecutor (); for (int i = 0; i <10; i ++) {final int index = i; SINGLETHREADEXECUTOR.EXECUTE (new runnable () {@Override public void run () {try {system.out.println (thread.currentThread (). getName () + "," + index); thread.seLep (2000);} catch (interrompedexception e) {e.printstacktrace ();}});};}Información de la consola
grupo-1-hilo-1,0
grupo-1-hilo-1,1
grupo-1-hilo-1,2
grupo-1-hilo-1,3
grupo-1-hilo-1,4
Envíe tareas al grupo de subprocesos. La diferencia entre Execute () y Subt () en la clase ThreadPoolExecutor es en realidad un método declarado en el ejecutor. Se implementa en ThreadPoolExecutor. Este método es el método central de ThreadPoolExecutor. A través de este método, se puede enviar una tarea al grupo de subprocesos y entregarse al grupo de subprocesos para su ejecución.
El método Subt () es un método declarado en EjecutorService. Se ha implementado en el AbstractExecutorService. No se reescribe en ThreadpoolExecutor. Este método también se usa para enviar tareas al grupo de subprocesos. Sin embargo, es diferente del método Execute (). Puede devolver el resultado de la ejecución de la tarea. Verifique la implementación del método Subt () a través del código fuente y encontrará que en realidad es el método ejecutado () llamado, pero utiliza Future para obtener el resultado de ejecución de la tarea.
/** * @throws RechleDEdExecutionException {@inheritdoc} * @throws nullPointerException {@inheritdoc} */public future <?> Subt (runnable tarea) {if (tarea ==) tirar nueva nullpointerException (); RunnableFuture <Void> ftask = newTaskfor (tarea, nulo); ejecutar (ftask); devolver ftask;}Cerrar el grupo de subprocesos podemos cerrar el grupo de hilos llamando al método de cierre o apagado del grupo de subprocesos, pero sus principios de implementación son diferentes. El principio de cierre es simplemente establecer el estado del grupo de hilos en el estado de apagado, e luego interrumpir todos los hilos que no están ejecutando tareas. El principio de ShutdownNow es atravesar los hilos del trabajador en el grupo de subprocesos, y luego llamar al método de interrupción del hilo uno por uno para interrumpir el hilo, por lo que las tareas que no pueden responder a las interrupciones nunca pueden finalizarse. ShutdownNow primero establecerá el estado del grupo de hilos para detener, luego intente detener todos los hilos que están ejecutando o pausando tareas, y volver a la lista de las tareas que se ejecutan.
Mientras se llame uno de estos dos métodos de cierre, el método ISSHUTDOWN devolverá verdadero. Cuando todas las tareas se han cerrado, significa que el grupo de subprocesos está cerrado con éxito. Llamar al método ISTerminaed devolverá verdadero. En cuanto a qué método debemos llamar para cerrar el grupo de subprocesos, debe determinarse por las características de la tarea enviadas al grupo de subprocesos. Por lo general, se llama a apagado para cerrar la piscina de hilo. Si la tarea no tiene que ser ejecutada, se puede llamar a ShutdownNow.
3. Análisis del grupo de hilos
Análisis de procesos: el flujo de trabajo principal del grupo de subprocesos se muestra en la figura a continuación: el flujo de trabajo principal del grupo de hilos Java
De la figura anterior podemos ver que al enviar una nueva tarea al grupo de subprocesos, el flujo de procesamiento del grupo de subprocesos es el siguiente:
** Análisis del código fuente. ** El análisis de proceso anterior nos permite comprender intuitivamente el principio de trabajo de los grupos de subprocesos. Usemos el código fuente para ver cómo se implementa. El grupo de subprocesos ejecuta tareas de la siguiente manera:
public void Ejecute (comando runnable) {if (command == null) lanzar nueva nullpointerException (); int c = ctl.get (); if (WorkerCountOf (c) <corePoolSize) {if (addworker (command, true)) return; c = ctl.get (); } if (isRunning (c) && workqueue.offer (command)) {int reconocido = ctl.get (); if (! isrunning (recwkck) && eliminar (comando)) rechazar (comando); else if (WorkerCountOf (Recwkeck) == 0) addWorker (nulo, falso); } else if (! addworker (comando, falso)) rechazar (comando);} Hilo de trabajadores. Cuando un grupo de hilo crea un hilo, encapsulará el hilo en un hilo de trabajador. Después de que el trabajador ejecute la tarea, también se hundirá infinitamente para obtener tareas en la cola de trabajo para ejecutar.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.