线程组介绍
线程组(ThreadGroup
)简单来说就是一个线程集合。线程组的出现是为了更方便地管理线程。
线程组是父子结构的,一个线程组可以集成其他线程组,同时也可以拥有其他子线程组。从结构上看,线程组是一个树形结构,每个线程都隶属于一个线程组,线程组又有父线程组,这样追溯下去,可以追溯到一个根线程组——System线程组。
![thread-group-tree](https://ucc.alicdn.com/images/user-upload-01/img_convert/c0e9ce5567a521ed2a07260181a70822.gif)
下面介绍一下线程组树的结构:
- JVM创建的system线程组是用来处理JVM的系统任务的线程组,例如对象的销毁等。
- system线程组的直接子线程组是main线程组,这个线程组至少包含一个main线程,用于执行main方法。
- main线程组的子线程组就是应用程序创建的线程组。
你可以在main方法中看到JVM创建的system线程组和main线程组:
public static void main(String[] args) {
ThreadGroup mainThreadGroup=Thread.currentThread().getThreadGroup();
ThreadGroup systenThreadGroup=mainThreadGroup.getParent();
System.out.println("systenThreadGroup name = "+systenThreadGroup.getName());
System.out.println("mainThreadGroup name = "+mainThreadGroup.getName());
}
console输出:
systenThreadGroup name = system
mainThreadGroup name = main
一个线程可以访问其所属线程组的信息,但不能访问其所属线程组的父线程组或者其他线程组的信息。
线程组的构造
java.lang.ThreadGroup
提供了两个构造函数:
Constructor | Description |
---|---|
ThreadGroup(String name) | 根据线程组名称创建线程组,其父线程组为main线程组 |
ThreadGroup(ThreadGroup parent, String name) | 根据线程组名称创建线程组,其父线程组为指定的parent线程组 |
下面演示一下这两个构造函数的用法:
public static void main(String[] args) {
ThreadGroup subThreadGroup1 = new ThreadGroup("subThreadGroup1");
ThreadGroup subThreadGroup2 = new ThreadGroup(subThreadGroup1, "subThreadGroup2");
System.out.println("subThreadGroup1 parent name = " + subThreadGroup1.getParent().getName());
System.out.println("subThreadGroup2 parent name = " + subThreadGroup2.getParent().getName());
}
console输出:
subThreadGroup1 parent name = main
subThreadGroup2 parent name = subThreadGroup1
ThreadGroup方法介绍
ThreadGroup提供了很多有用的方法,下面提供了这些方法的简要介绍,以及部分方法的使用示例。
S.N. | Method | Description |
---|---|---|
1) | void checkAccess() | This method determines if the currently running thread has permission to modify the thread group. |
2) | int activeCount() | This method returns an estimate of the number of active threads in the thread group and its subgroups. |
3) | int activeGroupCount() | This method returns an estimate of the number of active groups in the thread group and its subgroups. |
4) | void destroy() | This method destroys the thread group and all of its subgroups. |
5) | int enumerate(Thread[] list) | This method copies into the specified array every active thread in the thread group and its subgroups. |
6) | int getMaxPriority() | This method returns the maximum priority of the thread group. |
7) | String getName() | This method returns the name of the thread group. |
8) | ThreadGroup getParent() | This method returns the parent of the thread group. |
9) | void interrupt() | This method interrupts all threads in the thread group. |
10) | boolean isDaemon() | This method tests if the thread group is a daemon thread group. |
11) | void setDaemon(boolean daemon) | This method changes the daemon status of the thread group. |
12) | boolean isDestroyed() | This method tests if this thread group has been destroyed. |
13) | void list() | This method prints information about the thread group to the standard output. |
14) | boolean parentOf(ThreadGroup g) | This method tests if the thread group is either the thread group argument or one of its ancestor thread groups. |
15) | void suspend() | This method is used to suspend all threads in the thread group. |
16) | void resume() | This method is used to resume all threads in the thread group which was suspended using suspend() method. |
17) | void setMaxPriority(int pri) | This method sets the maximum priority of the group. |
18) | void stop() | This method is used to stop all threads in the thread group. |
19) | String toString() | This method returns a string representation of the Thread group. |
查看线程组信息
下面演示了查看当前线程组的信息。
public static void list(){
ThreadGroup tg = new ThreadGroup ("subgroup 1");
Thread t1 = new Thread (tg, "thread 1");
Thread t2 = new Thread (tg, "thread 2");
Thread t3 = new Thread (tg, "thread 3");
tg = new ThreadGroup ("subgroup 2");
Thread t4 = new Thread (tg, "my thread");
tg = Thread.currentThread ().getThreadGroup ();
int agc = tg.activeGroupCount ();
System.out.println ("Active thread groups in " + tg.getName () + " thread group: " + agc);
tg.list ();
}
输出如下:
Active thread groups in main thread group: 2
java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
java.lang.ThreadGroup[name=subgroup 1,maxpri=10]
java.lang.ThreadGroup[name=subgroup 2,maxpri=10]
终止线程组中的所有线程
一个线程应由其他线程来强制中断或停止,而是应该由线程自己自行停止。
因此 Thread.currentThread().stop()
, Thread.currentThread().suspend()
, Thread.currentThread().resume()
都已经被废弃了。
interrupt()
方法的作用是通知线程应该中断了,具体到底中断还是继续运行,由被通知的线程处理。
public class ThreadGroupExampleInterrupt {
public static void main(String[] args) {
// Start two threads
MyThread mt = new MyThread();
mt.setName("A");
mt.start();
mt = new MyThread();
mt.setName("B");
mt.start();
// Wait 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Interrupt all methods in the same thread group as the main thread
Thread.currentThread().getThreadGroup().interrupt();
}
//一个启动以后进入等待,直到被interrupt的线程
static class MyThread extends Thread {
public void run() {
synchronized ("A") {
System.out.println(getName() + " about to wait.");
try {
"A".wait();
} catch (InterruptedException e) {
System.out.println(getName() + " interrupted.");
}
System.out.println(getName() + " terminating.");
}
}
}
}
执行main
方法输出:
A about to wait.
B about to wait.
A interrupted.
A terminating.
B interrupted.
B terminating.
总结
本节介绍了线程组(ThreadGroup
)的概念,及其结构和构造函数,并演示了使用线程组方便地管理组内线程的几个方法。
本节是并发系列教程的一节,更多相关教程可以访问文章后面的链接。
后续会有更多关于并发编程的知识点的介绍,并且会结合企业项目进行实战介绍,欢迎继续关注。
Links
作者资源
- Java并发 之 线程池系列 (1) 让多线程不再坑爹的线程池
- Java并发 之 线程池系列 (2) 使用ThreadPoolExecutor构造线程池
- Java并发 Future系列 之 Future的介绍和基本用法
- Java并发 线程通信系列 之 Wait和Notify