ThreadGroup 与 Thread
默认情况下,新的线程都会加入到创建它的线程(也就是父线程)所在的 group 中。如同线程存在父子关系一样,ThreadGroup 同样也存在父子关系。
image.png创建 ThreadGroup
创建 ThreadGroup 非常简单,可通过两个构造函数来创建。
- public ThreadGroup(String name)
- public ThreadGroup(ThreadGroup parent, String name)
public static void main(String[] args) {
//指定名称不指定父线程组 (默认父线程组为创建线程组的线程的线程组,也就是当前线程的父线程组)
ThreadGroup myGroup = new ThreadGroup("myGroup");
//指定名称 指定父线程组
ThreadGroup myGroup2 = new ThreadGroup(myGroup, "myGroup2");
}
复制 Thread
- public int enumerate(Thread list[])
- public int enumerate(Thread list[], boolean recurse)
两个方法,都可以讲 Thread 中的 active 线程全部复制到 Thread 数组中,其中 recurse 参数如果为 true,则会将所有的自 group 中的 active 线程都递归到 Thread 数组中,enumerate(Thread list[])等价于enumerate(Thread list[], true),如果为 false,只会复制调用此方法的线程组中的 active 线程,其子线程组中的 active 线程不会复制
public static void main(String[] args) {
//指定名称不指定父线程组 (默认父线程组为创建线程组的线程的线程组,也就是当前线程的父线程组)
ThreadGroup myGroup = new ThreadGroup("myGroup");
Thread thread3 = new Thread(myGroup,new Runnable() {
@Override
public void run() {
while(true){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread3.start();
//指定名称 指定父线程组
ThreadGroup myGroup2 = new ThreadGroup(myGroup, "myGroup2");
Thread thread = new Thread(myGroup2,new Runnable() {
@Override
public void run() {
while(true){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread thread1 = new Thread(myGroup2,new Runnable() {
@Override
public void run() {
while(true){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
thread1.start();
System.out.println("activecount: "+myGroup.activeCount());
//myGroup.activeCount() 获取线程组中的 active 线程数,包括子线程组中的
Thread[] t = new Thread[myGroup.activeCount()];
// int size = myGroup.enumerate(t,true);
int size = myGroup.enumerate(t,false);
System.out.println("size: "+size);
}
enumerate 方法获取的线程仅仅是个预估值,并不能百分之百地保证当前 group 的活跃线程,比如在调用复制之后,某个线程结束了声明周期或者新的线程加入了进来,都会导致数据不准确。
enumerate 方法返回值是本次复制,active 线程真实的数量。
复制 ThreadGroup 数组
- public int enumerate(ThreadGroup list[])
- public int enumerate(ThreadGroup list[], boolean recurse)
和复制 Thread 数组类似,上面两个方法主要用于复制当前 ThreadGroup 的子 Group,同样 recurse 会决定是否复制子 Group 中的子 Group。
ThreadGroup 操作
ThreadGroup 并不能提供对线程的管理,ThreadGroup 的主要功能是对线程进行组织。
- activeCount() 用于获取 group 中活跃的线程,这只是个估计值,并不能百分之百的保证正确。
- activeGroupCount() 获取 group 中活跃的子 group,这也是一个估值,方法方法会递归获取所有子 group。
- getMaxPriority() 用于获取 group 的优先级,默认情况下,Group 的优先级为 10,在group 中,所有线程的优先级都不能大于 group 的优先级
- getName() 获取 group 的名字
- getParent() 用于获取 group 的父 group,如果父 group 不存在,则会返回 null,比如 system group 的父 group 就为 null。
- list() 该方法没有返回值,调用该方法会将 group 中所有的活跃线程信息全部输出到控制台,也就是 System.out
- parentOf(ThreadGroup g) 会判当前 group 是不是传入 group 的父 group。如果传入的 group 就是自己本身,该方法也回返回 true。
- setMaxPriority(int pri) 指定 group 的最大优先级,最大优先级不能超过父 group 的最大优先级,执行该方法不仅会改变当前 group 的最大优先级,还会改变所有子 group 的最大优先级
ThreadGroup 的 interrupt
interrupt 一个 ThreadGroup 会导致该 group 中所有的 active 线程都被 interrupt,也就是说该 group 中所有子线程的 interrupt 标识都被设置了。
ThreadGroup 的 destroy
destroy 用于销毁 ThreadGroup,该方法只是针对一个没有任何 active 线程的 group 进行一次 destroy 标记,调用该方法的直接结果是在父 group 中将自己移除,调用 destroy 方法的前提是该 ThreadGroup 中所有的线程必须是空的,也就是说所有线程包括子 group 中所有线程都已经停止运行,如果有 active 线程存在,调用 destroy 方法则会抛出异常。
守护 ThreadGroup
线程可以设置为守护线程,ThreadGroup 也可以设置为守护 ThreadGroup,但是将一个 ThreadGroup 设置为 daemon,并不会影响线程的 daemon 属性,如果一个 ThreadGroup 被设置为守护,那么在该 group 中没有任何 active 线程的时候该 group 将自动 destroy。
网友评论