Un threadGroup no sólo puede contener threads, también puede contener otros ThreadGroups. El grupo principal en una aplicación Java es el grupo de threads llamado "main". Se pueden crear threads y grupos de threads dentro del grupo "main". También se pueden crear threads y grupos de threads dentro de subgrupos de "main" y así sucesivamente.Esto resulta en una herencia del tipo raiz de los threads y los grupos de threads.
La clase ThreadGroup tiene métodos que pueden ser categorizados de la siguiente forma:
El ThreadGroup proporciona un juego de métodos que maneja los threads y los subgrupos dentro de un grupo y permite que otros objetos le pregunten a ThreadGroup sobre su contenido. Por ejemplo, se puede llamar al método activeCount() para encontrar el número de threads activos
actualmente dentro del grupo. Este método se utiliza frecuentemente con el método enumerate() para obtener un array con las referencias de todos los threads activos en el ThreadGroup. Por ejemplo, el método listCurrentThreads() del siguiente ejemplo rellena un array con todos los threads activos en el grupo actual e impime sus nombres:
class EnumerateTest {
void listCurrentThreads() {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int numThreads;
Thread[] listOfThreads;
numThreads = currentGroup.activeCount();
listOfThreads = new Thread[numThreads];
currentGroup.enumerate(listOfThreads);
for (int i = 0; i < numThreads; i++) {
System.out.println("Thread #" + i + " = " + listOfThreads[i].getName());
}
}
}
Otros métodos de manejo de la colección proporcionados por la clase ThreadGroup incluyen activeGroupCount() y list().
La clase ThreadGroup soporta varios atributos que son seleccionados y recuperados para el grupo en su totalidad. Estos atributos incluyen la prioridad máxima que un thread puede tener dentro del grupo, si el grupo es un grupo "daemon", el nombre del grupo, y el nombre del padre del grupo.Los métodos que seleccionan y obtienen estos atributos operan a nivel de grupo. Esto es, pueden inspeccionar el atributo del objeto ThreadGroup, pero no afectan a los threads que hay dentro del grupo. El siguiente listado muestra los métodos de ThreadGropup que operan a nivel de grupo:
Así, por ejemplo, cuando se utiliza setMaxPriority() para cambiar la prioridad máxima del grupo, sólo está cambiando el atributo en el grupo, no está cambiando la prioridad de ninguno de los thread del grupo. Consideremos este pequeño programa que crea un grupo y un thread dentro de él:
- getMaxPriority(), y setMaxPriority()
- getDaemon(), y setDaemon()
- getName()
- getParent(), y parentOf()
- toString()
class MaxPriorityTest { public static void main(String[] args) { ThreadGroup groupNORM = new ThreadGroup( "Un grupo con prioridad normal"); Thread priorityMAX = new Thread(groupNORM, "Un thread con prioridad máxima"); // Selecciona la prioridad del thread al máximo (10) priorityMAX.setPriority(Thread.MAX_PRIORITY); // Selecciona la prioridad del grupo a normal (5) groupNORM.setMaxPriority(Thread.NORM_PRIORITY); System.out.println("Máxima prioridad del grupo = " + groupNORM.getMaxPriority()); System.out.println("Prioridad del Thread = " + priorityMAX.getPriority()); } }Cuando se crea el grupo groupNORM hereda su atributo de prioridad máxima desde su grupo padre. En este caso, la prioridad del grupo padre es la máxima (MAX_PRIORITY) permitida por el sistema de ejecuión de Java. Luego el programa selecciona la prioridad del thread priorityMAX al máximo permitido por el sistema Java. Luego el programa baja la prioridad del grupo a normal (NORM_PRIORITY). El método setMaxPriority() no afecta a la prioridad del thread priorityMAX, por eso en este punto, el thread priorityMAX tienen un prioridad de 10 que es mayor que la prioridad máxima de su grupo groupNORM. Esta es la salida del programa:Prioridad máxima del Grupo = 5 Prioridad del Thread = 10Como puedes ver un thread puede tener una prioridad superior que el máximo permitido por su grupo siempre que la prioridad del thread se haya seleccionado antes de haber bajado la prioridad máxima del grupo. La prioridad máxima de un grupo de threads se utiliza para limitar la prioridad de los threads cuando son creados dentro de un grupo o cuando se utiliza setPriority() para cambiar la prioridad del thread. Observa que setMaxPriority() también cambia la prioridad máxima de todos sus subgrupos.Sin embargo, el estado daemon de un grupo sólo se aplica al grupo. Cambiar el estado daemon de un grupo no afecta al estado daemon de los threads que hay dentro del grupo. Además, el estado daemon de un grupo no implica de ninguna forma el estado daemon de sus treads -- se puede poner cualquier thread dentro de un grupo de threads daemon. El daemon de un grupo de threads sólo implica que el grupo puede ser destruido cuando todos los threads se han terminado.
La clase ThreadGroup tiene tres métodos que le permiten modificar el estado actual de todos los threads de un grupo.Estos métodos aplican el cambio de estado apropiado a todos los threads del grupo y sus subgrupos.
- resume()
- stop()
- suspend()
La clase ThreadGroup por si misma no impone ninguna restricción de acceso, como permitir que los threads de un grupo puedan inspeccionar o medificar threads de un grupo diferente. Mas bien las clases Thread y ThreadGroup cooperan con los manejadores de seguridad (subclases de la clase java.lang.SecurityManager), que puede imponer restricciones de acceso basándose en los miembros de un grupo de threads.Las clases Thread y threadGroup tienen un método, checkAccess(), que llama al método checkAccess() del controlador de seguridad actual. El controlador de seguridad decide si permite el acceso basándose en los miembros del grupo de threads involucrado. Si el acceso no está permitido, el método checkAccess() lanza una excepción SecurityException. De otro modo el método checkAccess() simplemente retorna.
La siguiente lista muestra varios métodos de ThreadGroup que llaman a checkAccess() antes de realizar la acción del método. Esto se conoce como acceso regulado, esto es, accesos que deben ser aprobados por el controlador de seguridad antes de poder ser completados.
Esta es una lista de métodos de la clase Thread que llaman a checkAccess() antes de proceder:
- ThreadGroup(ThreadGroup padre, String nombre)
- setDaemon(boolean isDaemon)
- setMaxPriority(int maxPriority)
- stop()
- suspend()
- resume()
- destroy()
Una aplicación Java solitaria no tiene un controlador de seguridad por defecto. Esto es, por defecto, no se imponen restricciones a ningún thread para que pueda inspeccionar o modificar cualquier otro thread, sin importar el grupo en el que se encuetra. Se puede definir e implementar propias restricciones de acceso para los grupos de threads mediante la subclasificación de la clase SecurityManager, sobreescribiendo los métodos apropiados, e instalandolo como el controlador de seguridad para su aplicación.
- Constructores que especifican un grupo de threads.
- stop()
- suspend()
- resume()
- setPriority(int priority)
- setName(String name)
- setDaemon(boolean isDaemon)
El navegador HotJava es un ejemplo de aplicación que implementa su propio controlador de seguridad. HotJava necesita asegurarse de que los applets tengan un buen comportamiento y no hagan cosas sucias a otros applets que se están ejecutando al mismo tiempo (como bajar la prioridad de otros threads de otros applets). El controlador de seguridad de HotJava no permite que un thread modifique threads de otro grupo. Por favor, observa que las restricciones de acceso basadas en los grupos de threads pueden variar de un navegador a otro y por eso tus applets pueden tener comportamientos diferentes en diferentes navegadores.