¿Qué es una piscina de hilo?
Un grupo de subprocesos es una colección de hilos que [ejecución de bucle] múltiples lógica de aplicaciones en uno o más subprocesos.
En términos generales, los piscinas de hilos tienen las siguientes partes:
Uno o más hilos que completan la tarea principal.
Hilos de gestión utilizados para la gestión de programación.
La cola de tareas debe ser ejecutada.
La función del grupo de subprocesos:
La función de un grupo de subprocesos es limitar el número de subprocesos ejecutados en el sistema.
Dependiendo del entorno del sistema, el número de subprocesos se puede establecer automáticamente o manualmente para lograr el mejor efecto de operación; Se desperdician menos recursos del sistema y más congestión del sistema no es alta. Use un grupo de subprocesos para controlar el número de hilos, y otros hilos están esperando en línea. Después de ejecutar una tarea, la primera tarea se toma de la cola para comenzar la ejecución. Si no hay un proceso de espera en la cola, este recurso del grupo de hilos está esperando. Cuando se debe ejecutar una nueva tarea, si hay hilos de trabajadores que esperan en el grupo de subprocesos, puede comenzar a funcionar; De lo contrario, entrará en la cola de espera.
Implementar el grupo de hilos por usted mismo
Basado en la comprensión anterior de Thread Pool, escribimos nuestro propio grupo de hilos simple:
Interfaz simple de la piscina de hilos:
Public Interface ThreadPool <Job extiende Runnable> {// Ejecutar una tarea (trabajo), este trabajo debe implementar ejecutable ejecutivo de ejecución (trabajo de trabajo); // Cierre el cierre vacío del grupo de hilo (); // Aumentar el hilo del trabajador, es decir, el hilo utilizado para ejecutar la tarea void addWorkers (int num); // Reducir el hilo de trabajador Void RemoutWorker (int num); // Obtenga el número de tareas que esperan para ser ejecutadas void getJobSize ();}El cliente puede enviar el trabajo al grupo de subprocesos a través del método Ejecutar (trabajo) para su ejecución, y el cliente no tiene que esperar a que el trabajo se ejecute en absoluto. Además del método Ejecutar (Job), la interfaz de grupo de subprocesos proporciona métodos para aumentar/disminuir los hilos de los trabajadores y cerrar los grupos de subprocesos. Cada cliente envía un trabajo que ingresará una cola de trabajo y esperará a que el hilo del trabajador procese.
La implementación predeterminada de la interfaz de grupo de subprocesos
clase pública predeterminadaThreadPool <Job extiende Runnable> implementa Threadpool <BOB> {// Número máximo de subprocesos para subprocesos de mantenimiento del grupo TRABAJO PRIVADO ESTÁTICO INT MAX_WORKER_NUMBERS = 10; // Valor predeterminado del hilo de mantenimiento del grupo de subprocesos de hilo privado estático final int default_worker_numbers = 5; // Número mínimo de trabajador de mantenimiento del grupo de subprocesos PRIVEST STICATIC FINAL INT MIN_WORKER_NUMBERS = 1; // Mantener una lista de trabajo, que agrega el trabajo iniciado por el cliente, LinkedList final de LinkedList <Bobr> Jobs = new LinkedList <BOB> (); // Lista de hilos de trabajadores Lista final privada <VERSER> trabajadores = colección.synChronizedList (new ArrayList <Worker> ()); // Número de hilos de trabajadores private int workernum; // Generar private atomiclong threadnum = new AtomicLong (); // Generar el grupo de subprocesos públicos defaultThreadPool () {this.workernum = default_worker_numbers; InitializeWorkers (this.workernum); } public DefaultThreadPool (int num) {if (num> max_worker_numbers) {this.workernum = default_worker_numbers; } else {this.workernum = num; } InitializeWorkers (this.workernum); } // Inicializar cada hilo de trabajador Void privado InitializeWorkers (int num) {for (int i = 0; i <num; i ++) {Worker Worker = New Worker (); // agregar a la lista de trabajadores hilos trabajadores.add (trabajador); // Inicie el hilo de trabajador hilo de hilo = nuevo hilo (trabajador); Thread.Start (); }} public void ejecute (trabajo de trabajo) {if (trabajo! = null) {// de acuerdo con el "espere/notificar el mecanismo" del hilo, debemos bloquear los trabajos sincronizados (trabajos) {Jobs.addlast (trabajo); Jobs.notify (); }}} // Cierre el grupo de subprocesos que cerrará cada hilo de trabajador público vacío cierre () {para (trabajador w: trabajadores) {w.shutdown (); }}} // Agregar hilo de trabajador public void addWorkers (int num) {// Agregar bloqueo para evitar que el hilo aumente o complete mientras el siguiente subproceso continúa aumentando, lo que hace que el hilo de trabajadores exceda el valor máximo sincronizado (trabajos) {if (num + this.workernum> max_worker_numbers) {num_work_numbers - this.workernum; } InitializeWorkers (num); this.workernum += num; }} // Reducir el hilo de trabajador public void removeworker (int num) {sincronizado (trabajos) {if (num> = this.workernum) {tirar nueva ilegalargumentException ("exceder el número de hilos existentes"); } para (int i = 0; i <num; i ++) {trabajador trabajador = trabajadores.get (i); if (trabajador! = null) {// cierre el hilo y elimine trabajador.shutdown (); trabajadores.remove (i); }} this.workernum -= num; }} public int getJobSize () {// TODO Auto Generado Método STUB Return Workers.size (); } // Defina el hilo de trabajador implementos de trabajo de trabajo runnable {// indica si el trabajador privado boolean volátil running = true; public void run () {while (ejecutando) {trabajo trabajo = null; // Mecanismo de espera/notificación de hilo Sincronizado (Jobs) {if (Jobs.isEmpty ()) {try {Jobs.wait (); // El hilo espera a la activación} Catch (InterruptedException e) {// detecta la operación de interrupción externa en el hilo y devuelve el hilo. CurrentThread (). Interrupt ();; devolver; }} // Tome un trabajo Job = Jobs.RemoveFirst (); } // ejecutar trabajo if (trabajo! = Null) {job.run (); }}} // Terminar el hilo public void shutdown () {running = false; }}}
Desde la implementación del grupo de subprocesos, se puede ver que cuando el cliente llama al método Ejecutivo (trabajo), agregará constantemente trabajos a los trabajos de la lista de tareas, y cada hilo de trabajadores no leerá los trabajos de los trabajos para ejecutar. Cuando los trabajos están vacíos, el hilo del trabajador ingresa al estado de espera.
Después de agregar un trabajo, se llama al método notify () en los trabajos de cola de trabajo para despertar un hilo de trabajadores. Aquí no llamamos a notifyall () para evitar desperdiciar recursos moviendo todos los hilos en la cola de espera a la cola de bloqueo.
La esencia de un grupo de subprocesos es usar una cola de trabajo segura de hilo para conectar los subprocesos de trabajadores y los hilos del cliente. El hilo del cliente regresa después de poner la tarea en la cola de trabajo, mientras que el hilo del trabajador toma mal el trabajo de la cola de trabajo y la ejecuta. Cuando la cola de trabajo está vacía, el hilo del trabajador ingresa al estado de espera. Cuando un cliente envía una tarea, pasará por cualquier hilo de trabajador. Con la presentación de una gran cantidad de tareas, se despiertan más hilos de trabajadores.
Referencia: "El arte de la programación concurrente en Java" Fang Tengfei