允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。
1.首先,每个线程都有一个所属的线程组,在我们创建一个thread的时候虽然我们没有指定这个线程所在的线程组,但是初始化的的时候会默认添加到当前线程所在的线程组。
即A线程创建B线程,如果没有指定B所在的线程组,那B的线程组就是A所在的组。
thread的初始化函数如下:
private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
Thread currentThread = Thread.currentThread();
if (group == null) {
group = currentThread.getThreadGroup();
}
2.此类存在的意义应该是对多线程进行统一管理而设置的。假设有10个线程,我们放在同一个组里面,那我们可以同时中断interrupt()
和同时销毁destroy()
这10个线程。
或者设置相同的优先级setMaxPriority。
3.既然threadgroup内部存储结构是一棵树,那我们很明显可以知道他有一个父group和很多子节点threadgroup,还有很多的叶子节点thread。
其源码为:
// 父节点,当前group所在的group
final ThreadGroup parent;
/**这个不懂了
* Weak references to the threads in this group.
* Access is guarded by synchronizing on this field.
*/
private final List<WeakReference<Thread>> threadRefs = new ArrayList<WeakReference<Thread>>(5);
/**
* 叶子节点集合
*/
private final Iterable<Thread> threads = CollectionUtils.dereferenceIterable(threadRefs, true);
/**
* 子节点集合
*/
private final List<ThreadGroup> groups = new ArrayList<ThreadGroup>(3);
/* jvm的系统group。static是jvm级别数据,当前虚拟机只有同一份的。感觉应该是main函数所在的group
static final ThreadGroup mSystem = new ThreadGroup();
static final ThreadGroup mMain = new ThreadGroup(mSystem, "main");
其他的一些增删改查就和树结构没啥区别。
4.我们常用的函数是中断此线程组的线程,其api代码如下
public final void interrupt() {
synchronized (threadRefs) {
for (Thread thread : threads) {
thread.interrupt();
}
}
synchronized (groups) {
for (ThreadGroup group : groups) {
group.interrupt();
}
}
}
5.还有一个更重要的功能是处理此线程组的异常信息。