文章目录
- 1. 简介
- 2. 线程对象关联线程组:一级关联
- 3. 线程对象关联线程组:多级关联
- 4. 自动归属属性
- 5. 获取根线程组
1. 简介
为了方便某些具有相同功能的线程进行管理,我们可以把线程归属到某一个线程组。线程组中可以有线程对象、线程,类似于树的形式。Java线程组(Thread Group)是一种用于组织线程的机制。线程组可以将一组线程作为一个单元进行管理,并且可以方便地对这组线程进行控制和监视。线程组可以形成一个层次结构,其中每个线程组都可以包含其他线程组和线程。线程组提供了以下功能:
- 线程组可以用于设置线程的优先级、守护状态和未捕获异常处理器。
- 可以通过调用线程组的
interrupt()
方法中断线程组中的所有线程。 - 可以通过调用线程组的
stop()
方法停止线程组中的所有线程。 - 可以使用线程组的
enumerate()
方法获取线程组中的所有线程。
线程组的作用就是可以批量的管理线程或线程对象,有效地对线程或者线程对象进行组织。
2. 线程对象关联线程组:一级关联
在Java中,线程组中的一级关联是指将线程对象直接添加到线程组中。一级关联意味着线程对象直接属于线程组,而不是其他线程对象的子线程。当将线程对象添加到线程组中时,该线程对象成为线程组的成员,可以通过线程组来管理和控制该线程对象。线程组可以对其成员线程执行一些集体操作,例如设置优先级、中断、停止等。线程组中的一级关联可以使用以下构造函数来实现:
ThreadGroup(ThreadGroup parent, String name)
测试代码如下:
public class Main {
public static void main(String[] args) {
// 创建线程组
ThreadGroup threadGroup = new ThreadGroup("MyThreadGroup");
// 创建线程,并将线程添加到线程组
Thread thread1 = new Thread(threadGroup, new MyThread(), "Thread 1");
Thread thread2 = new Thread(threadGroup, new MyThread(), "Thread 2");
// 启动线程
thread1.start();
thread2.start();
// 输出线程组中的活动线程数
System.out.println("Active threads in Thread Group: " + threadGroup.activeCount());
// 输出线程组的名称
System.out.println("Thread Group Name: " + threadGroup.getName());
// 列举线程组中的线程
Thread[] threads = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(threads);
System.out.println("Threads in Thread Group:");
for (Thread thread : threads) {
System.out.println(thread.getName());
}
}
}
class MyThread extends Thread{
@Override
public void run(){
System.out.println("Thread: " + Thread.currentThread().getName() + " is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
3. 线程对象关联线程组:多级关联
多级关联是指线程组中的线程对象可以继续创建其他线程组,并形成一个层次结构。通过多级关联,可以更好地组织和管理线程,形成更复杂的线程结构。
public class Main implements Runnable{
public void run() {
System.out.println("Thread: " + Thread.currentThread().getName() + " is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
// 创建顶级线程组
ThreadGroup parentGroup = new ThreadGroup("ParentThreadGroup");
// 创建子线程组
ThreadGroup childGroup1 = new ThreadGroup(parentGroup, "ChildThreadGroup1");
ThreadGroup childGroup2 = new ThreadGroup(parentGroup, "ChildThreadGroup2");
// 创建线程,并将线程添加到子线程组
Thread thread1 = new Thread(childGroup1, new Main(), "Thread 1");
Thread thread2 = new Thread(childGroup2, new Main(), "Thread 2");
// 启动线程
thread1.start();
thread2.start();
// 输出线程组的名称和活动线程数
System.out.println("Parent Thread Group Name: " + parentGroup.getName());
System.out.println("Child Thread Group 1 Name: " + childGroup1.getName());
System.out.println("Child Thread Group 2 Name: " + childGroup2.getName());
System.out.println("Active threads in Parent Thread Group: " + parentGroup.activeCount());
// 列举父线程组中的线程
Thread[] parentThreads = new Thread[parentGroup.activeCount()];
parentGroup.enumerate(parentThreads);
System.out.println("Threads in Parent Thread Group:");
for (Thread thread : parentThreads) {
System.out.println(thread.getName());
}
// 列举子线程组1中的线程
Thread[] childThreads1 = new Thread[childGroup1.activeCount()];
childGroup1.enumerate(childThreads1);
System.out.println("Threads in Child Thread Group 1:");
for (Thread thread : childThreads1) {
System.out.println(thread.getName());
}
// 列举子线程组2中的线程
Thread[] childThreads2 = new Thread[childGroup2.activeCount()];
childGroup2.enumerate(childThreads2);
System.out.println("Threads in Child Thread Group 2:");
for (Thread thread : childThreads2) {
System.out.println(thread.getName());
}
}
}
4. 自动归属属性
在Java中,线程对象具有自动归属属性(Automatic Thread Grouping),这意味着在创建线程对象时,它会自动归属于其创建线程的线程组。当您创建一个线程对象时,如果当前线程存在一个线程组,新创建的线程对象将自动成为当前线程所属线程组的一员。这种自动归属属性可以简化线程组的管理,无需显式指定线程组。
public class Main implements Runnable{
public void run() {
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("Thread: " + Thread.currentThread().getName() + " belongs to Thread Group: " + threadGroup.getName());
}
public static void main(String[] args) {
//看看主线程属于哪个组
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("Main Thread: " + Thread.currentThread().getName() + " belongs to Thread Group: " + threadGroup.getName());
// 创建线程
Thread thread1 = new Thread(new Main(), "Thread 1");
Thread thread2 = new Thread(new Main(), "Thread 2");
// 启动线程
thread1.start();
thread2.start();
}
}
5. 获取根线程组
上面的方法我们知道了Main线程属于Main线程组,那么Main线程组的父线程组是什么,我们研究一下
public class Main{
public static void main(String[] args) {
//看看主线程属于哪个组
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("Main Thread: " + Thread.currentThread().getName() + " belongs to Thread Group: " + threadGroup.getName());
System.out.println("Main Thread`s Parent ThreadGroup is:"+Thread.currentThread().getThreadGroup().getParent().getName());
System.out.println("Main Thread`s GrandParent ThreadGroup is:"+Thread.currentThread().getThreadGroup().getParent().getParent().getName());
}
}
可见Main线程的父线程组是System线程组,再取父线程则出现空异常