La agrupación de subprocesos es una característica interesante proporcionada por la API de concurrencia de Java. Podemos tratar un grupo de subprocesos como una unidad independiente y podemos manipular los objetos de subprocesos en el grupo de subprocesos a voluntad. Por ejemplo, puede controlar un grupo de subprocesos para ejecutar la misma tarea sin preocuparse por cuántos subprocesos aún se están ejecutando, y también puede usar una llamada de interrupción para interrumpir la ejecución de todos los subprocesos.
Java proporciona la clase ThreadGroup para controlar un grupo de subprocesos. Se puede crear un grupo de subprocesos a través de un objeto de subproceso, o puede ser creado por otros grupos de subprocesos para generar una estructura de árbol de subprocesos.
Según "Effective Java", ya no se recomienda el uso de ThreadGroup. Se recomienda utilizar Ejecutor.
——D Guagot explica esto.
En esta sección, utilizamos ThreadGroup para desarrollar un ejemplo sencillo. Crearemos diez hilos con diferentes tiempos de suspensión (como simulando una búsqueda) y cuando uno de ellos se complete, interrumpiremos el resto.
lo sabes
Siga los pasos que se muestran a continuación para completar el código de muestra.
1. Cree una clase llamada Resultado para almacenar el nombre del primer hilo que completa la tarea. Declare una variable privada de tipo String, nombre y genere métodos Setter/Getter. El código es el siguiente:
Copie el código de código de la siguiente manera:
Resultado de clase pública {
nombre de cadena privada;
cadena pública getName() {
nombre de retorno;
}
setName público vacío (nombre de cadena) {
this.nombre = nombre;
}
}
2. Cree una clase llamada SearchTask e implemente la interfaz Runnable. El código es el siguiente:
Copie el código de código de la siguiente manera:
La clase pública SearchTask implementa Runnable {
3. Declare una variable privada de tipo Resultado y cree una instancia de la variable a través del constructor. El código es el siguiente:
Copie el código de código de la siguiente manera:
resultado resultado privado;
tarea de búsqueda pública (resultado del resultado) {
this.resultado = resultado;
}
4. Implemente el método run() y llame al método doTask() para esperar a que se complete o se interrumpa. Este método también imprime información en la consola para mostrar el inicio, el final o la interrupción del hilo. El código es el siguiente:
Copie el código de código de la siguiente manera:
@Anular
ejecución pública vacía() {
Nombre de cadena = Thread.currentThread().getName();
System.out.printf("Subproceso %s: Inicio/n", nombre);
intentar {
realizarTarea();
resultado.setName(nombre);
} captura (Excepción interrumpida e) {
System.out.printf("Subproceso %s: Interrumpido/n", nombre);
devolver;
}
System.out.printf("Subproceso %s: Fin/n", nombre);
}
5. Implemente el método doTask (), que creará un objeto aleatorio y luego usará el objeto para generar un número aleatorio para ajustar el tiempo de suspensión del hilo. El código es el siguiente:
Copie el código de código de la siguiente manera:
// Simular búsqueda
doTask vacío privado () lanza InterruptedException {
Aleatorio aleatorio = nuevo Aleatorio(nueva Fecha().getTime());
valor int = (int) (random.nextDouble() * 100);
System.out.printf("Subproceso %s: %d/n",
Thread.currentThread().getName(), valor);
TimeUnit.SECONDS.sleep(valor);
}
6. Cree la clase principal del programa de muestra, Main, e implemente el método main(). El código es el siguiente:
Copie el código de código de la siguiente manera:
clase pública principal {
público estático vacío principal (String [] argumentos) {
7. Cree un objeto ThreadGroup denominado Buscador. El código es el siguiente:
Copie el código de código de la siguiente manera:
ThreadGroup threadGroup = new ThreadGroup("Buscador");
8. Luego, cree un objeto Resultado y un objeto SearchTask. El código es el siguiente:
Copie el código de código de la siguiente manera:
Resultado resultado = nuevo resultado();
SearchTask searchTask = nueva SearchTask(resultado);
9. Utilice el objeto SearchTask para crear diez objetos Thread y, al crear un objeto Thread, pase el objeto ThreadGroup como primer parámetro al constructor de la clase Thread. El código es el siguiente:
Copie el código de código de la siguiente manera:
para (int i = 0; i < 5; i++) {
Hilo hilo = nuevo hilo (threadGroup, searchTask);
hilo.start();
intentar {
Unidad de tiempo.SEGUNDOS.dormir(1);
} captura (Excepción interrumpida e) {
e.printStackTrace();
}
}
10. Utilice el método list() para imprimir la información del objeto ThreadGroup. El código es el siguiente:
Copie el código de código de la siguiente manera:
System.out.printf("Número de subprocesos: %d/n", threadGroup.activeCount());
System.out.println("Información sobre el grupo de subprocesos");
threadGroup.lista();
11. Utilice activeCount() y enumerate() para obtener el número de subprocesos activos en el objeto ThreadGroup y cópielo en una matriz de subprocesos. Utilice el método get*() para obtener el nombre y el estado del hilo. El código es el siguiente:
Copie el código de código de la siguiente manera:
Hilo[] hilos = nuevo Hilo[threadGroup.activeCount()];
threadGroup.enumerate(hilos);
para (int i = 0; i < threadGroup.activeCount(); i++) {
System.out.printf("Subproceso %s: %s/n", subprocesos[i].getName(),
hilos[i].getState());
}
12. Llame al método waitFinish() y espere a que uno de los subprocesos del objeto ThreadGroup complete la tarea. Implemente este método más tarde. El código es el siguiente:
Copie el código de código de la siguiente manera:
esperarFinish(threadGroup);
13. Utilice el método de interrupción () para interrumpir otros subprocesos en el grupo de subprocesos. El código es el siguiente:
Copie el código de código de la siguiente manera:
threadGroup.interrupt();
14. Implemente el método waitFinish () y utilice el método activeCount () para controlar los resultados de ejecución del hilo. El código es el siguiente:
Copie el código de código de la siguiente manera:
//Esperar a que se complete la tarea
espera vacía estática privadaFinish (ThreadGroup threadGroup) {
mientras (threadGroup.activeCount() > 9) {
intentar {
Unidad de tiempo.SEGUNDOS.dormir(1);
} captura (Excepción interrumpida e) {
e.printStackTrace();
}
}
}
15. Ejecute el programa y verifique el efecto de ejecución.
saber por qué
A continuación se muestra el resultado de la ejecución del programa. Verá el resultado del método list(), el estado de cada hilo, etc.
Copie el código de código de la siguiente manera:
Hilo Hilo-0: Inicio
Hilo Hilo-0: 52
Hilo Hilo-1: Inicio
Hilo Hilo-1: 41
Hilo Hilo-2: Inicio
Hilo Hilo-2: 69
Hilo Hilo-3: Inicio
Hilo Hilo-3: 60
Hilo Hilo-4: Inicio
Hilo Hilo-4: 88
Número de hilos: 5
Información sobre el grupo de hilos
java.lang.ThreadGroup[nombre=Buscador,maxpri=10]
Hilo[Hilo-0,5,Buscador]
Hilo[Hilo-1,5,Buscador]
Hilo[Hilo-2,5,Buscador]
Hilo[Hilo-3,5,Buscador]
Hilo[Hilo-4,5,Buscador]
Hilo Hilo-0: TIMED_WAITING
Hilo Hilo-1: TIMED_WAITING
Hilo Hilo-2: TIMED_WAITING
Hilo Hilo-3: TIMED_WAITING
Hilo Hilo-4: TIMED_WAITING
Hilo Hilo-1: Interrumpido
Hilo Hilo-4: Interrumpido
Hilo Hilo-2: Interrumpido
Hilo Hilo-0: Interrumpido
Hilo Hilo-3: Interrumpido
La clase ThreadGroup almacena muchos objetos Thread y objetos ThreadGroup asociados. Puede acceder a la información del hilo llamando a los métodos de esta clase y también puede realizar varias operaciones en él, como interrupciones.
interminable
La clase ThreadGroup también tiene muchos métodos. Lea la documentación de la API para obtener descripciones completas de los métodos.
Usar doctrina
Este artículo está traducido del "Libro de cocina de concurrencia de Java 7" (D Gua Ge lo robó como "Colección de ejemplos de concurrencia de Java 7") y solo se utiliza como material de aprendizaje. No puede utilizarse con fines comerciales sin autorización.
Pequeño éxito
A continuación se muestra la versión completa del código utilizado en los ejemplos de esta sección.
Código completo de la clase Resultado:
Copie el código de código de la siguiente manera:
paquete com.diguage.books.concurrencycookbook.chapter1.recipe10;
/**
* Almacenar resultados de consultas
* Fecha: 2013-09-30
* Hora: 00:45
*/
Resultado de clase pública {
nombre de cadena privada;
cadena pública getName() {
nombre de retorno;
}
setName público vacío (nombre de cadena) {
this.nombre = nombre;
}
}
El código completo de la clase SearchTask es el siguiente:
paquete com.diguage.books.concurrencycookbook.chapter1.recipe10;
importar java.util.Fecha;
importar java.util.Random;
importar java.util.concurrent.TimeUnit;
/**
* Clase de búsqueda de simulación
* Fecha: 2013-10-02
* Hora: 22:38
*/
La clase pública SearchTask implementa Runnable {
resultado resultado privado;
tarea de búsqueda pública (resultado del resultado) {
this.resultado = resultado;
}
@Anular
ejecución pública vacía() {
Nombre de cadena = Thread.currentThread().getName();
System.out.printf("Subproceso %s: Inicio/n", nombre);
intentar {
realizarTarea();
resultado.setName(nombre);
} captura (Excepción interrumpida e) {
System.out.printf("Subproceso %s: Interrumpido/n", nombre);
devolver;
}
System.out.printf("Subproceso %s: Fin/n", nombre);
}
// Simular búsqueda
doTask vacío privado () lanza InterruptedException {
Aleatorio aleatorio = nuevo Aleatorio(nueva Fecha().getTime());
valor int = (int) (random.nextDouble() * 100);
System.out.printf("Subproceso %s: %d/n",
Thread.currentThread().getName(), valor);
TimeUnit.SECONDS.sleep(valor);
}
}
El código completo de la clase Main:
Copie el código de código de la siguiente manera:
paquete com.diguage.books.concurrencycookbook.chapter1.recipe10;
importar java.util.concurrent.TimeUnit;
/**
* Clase principal de ejemplo de grupo de subprocesos
* Fecha: 2013-10-02
* Hora: 22:45
*/
clase pública principal {
público estático vacío principal (String [] argumentos) {
ThreadGroup threadGroup = new ThreadGroup("Buscador");
Resultado resultado = nuevo resultado();
SearchTask searchTask = nueva SearchTask(resultado);
para (int i = 0; i < 5; i++) {
Hilo hilo = nuevo hilo (threadGroup, searchTask);
hilo.start();
intentar {
Unidad de tiempo.SEGUNDOS.dormir(1);
} captura (Excepción interrumpida e) {
e.printStackTrace();
}
}
System.out.printf("Número de subprocesos: %d/n", threadGroup.activeCount());
System.out.println("Información sobre el grupo de subprocesos");
threadGroup.lista();
Hilo[] hilos = nuevo Hilo[threadGroup.activeCount()];
threadGroup.enumerate(hilos);
para (int i = 0; i < threadGroup.activeCount(); i++) {
System.out.printf("Subproceso %s: %s/n", subprocesos[i].getName(),
hilos[i].getState());
}
esperarFinish(threadGroup);
threadGroup.interrupt();
}
//Esperar a que se complete la tarea
espera vacía estática privadaFinish (ThreadGroup threadGroup) {
mientras (threadGroup.activeCount() > 9) {
intentar {
Unidad de tiempo.SEGUNDOS.dormir(1);
} captura (Excepción interrumpida e) {
e.printStackTrace();
}
}
}
}