什么是线程组?你学会了吗?
2023-12-11 09:26:47 软件 193观看
摘要一、简介在之前的多线程系列文章中,我们陆陆续续的介绍了Thread线程类相关的知识和用法,其实在Thread类上还有一层ThreadGroup类,也就是线程组。今天我们就一起来简单的聊聊线程组相关的知识和用法。二、什么是线程组线

一、简介

在之前的多线程系列文章中,我们陆陆续续的介绍了Thread线程类相关的知识和用法,其实在Thread类上还有一层ThreadGroup类,也就是线程组。B0x28资讯网——每日最新资讯28at.com

今天我们就一起来简单的聊聊线程组相关的知识和用法。B0x28资讯网——每日最新资讯28at.com

二、什么是线程组

线程组,简单来说就是多个线程的集合,它的出现主要是为了更方便的管理线程。B0x28资讯网——每日最新资讯28at.com

从结构角度看,线程组与线程之间其实是一个父子结构,一个线程组可以拥有几个线程,同时也可以拥有几个线程组。整个组织结构像一棵树一样,每个线程一定有一个线程组,线程组可能又有一个父线程组,追溯到根节点就是一个系统线程组。B0x28资讯网——每日最新资讯28at.com

线程组与线程之间的关系,可以用如下图来描述。B0x28资讯网——每日最新资讯28at.com

图片图片B0x28资讯网——每日最新资讯28at.com

比如,我们通常创建的main方法,对应的是main线程,它所属的是main线程组,main线程组的父级是是system系统线程组。B0x28资讯网——每日最新资讯28at.com

public static void main(String[] args) {    Thread currentThread = Thread.currentThread();    ThreadGroup currentThreadGroup = currentThread.getThreadGroup();    ThreadGroup systemThreadGroup = currentThreadGroup.getParent();    System.out.println("currentThread:" + currentThread.getName());    System.out.println("currentThreadGroup:" + currentThreadGroup.getName());    System.out.println("systemThreadGroup:" + systemThreadGroup.getName());}

输出结果如下:B0x28资讯网——每日最新资讯28at.com

currentThread:maincurrentThreadGroup:mainsystemThreadGroup:system

其中system线程组就是根节点,再上一层就没有了,如果调用会抛空指针异常。B0x28资讯网——每日最新资讯28at.com

线程组最主要的作用是:可以实现批量管理线程或者线程组,有效的对线程或者线程组对象进行检查、尝试中断等操作。B0x28资讯网——每日最新资讯28at.com

下面我们就一起来看看ThreadGroup的常用方法和使用技巧。B0x28资讯网——每日最新资讯28at.com

三、线程组用法详解

3.1、构造方法介绍

ThreadGroup提供了两个构造方法,内容如下:B0x28资讯网——每日最新资讯28at.com

方法B0x28资讯网——每日最新资讯28at.com

描述B0x28资讯网——每日最新资讯28at.com

ThreadGroup(String name)B0x28资讯网——每日最新资讯28at.com

根据线程组名称创建线程组,其父线程组为main线程组B0x28资讯网——每日最新资讯28at.com

ThreadGroup(ThreadGroup parent, String name)B0x28资讯网——每日最新资讯28at.com

根据线程组名称创建线程组,其父线程组为指定的 parent 线程组B0x28资讯网——每日最新资讯28at.com

其中支持指定父级线程组的方法,在实际的使用中比较常见。B0x28资讯网——每日最新资讯28at.com

下面,我们演示一下这两个构造函数的用法:B0x28资讯网——每日最新资讯28at.com

public static void main(String[] args) {    ThreadGroup subThreadGroup1 = new ThreadGroup("sub1");    ThreadGroup subThreadGroup2 = new ThreadGroup(subThreadGroup1, "sub2");    System.out.println("sub1 parent thread group name:" + subThreadGroup1.getParent().getName());    System.out.println("sub2 parent thread group name:" + subThreadGroup2.getParent().getName());}

输出结果如下:B0x28资讯网——每日最新资讯28at.com

sub1 parent thread group name:mainsub2 parent thread group name:sub1

3.2、核心方法介绍

ThreadGroup提供了很多有用的方法,下面整理了一些方法的简要介绍,内容如下:B0x28资讯网——每日最新资讯28at.com

方法B0x28资讯网——每日最新资讯28at.com

描述B0x28资讯网——每日最新资讯28at.com

public final String getName()B0x28资讯网——每日最新资讯28at.com

返回此线程组的名称B0x28资讯网——每日最新资讯28at.com

public final ThreadGroup getParent()B0x28资讯网——每日最新资讯28at.com

返回此线程组的父级B0x28资讯网——每日最新资讯28at.com

public final boolean parentOf(ThreadGroup g)B0x28资讯网——每日最新资讯28at.com

测试此线程组是线程组参数还是其父级线程组之一B0x28资讯网——每日最新资讯28at.com

public int activeCount()B0x28资讯网——每日最新资讯28at.com

返回此线程组及其子组中活动线程的数量的估计值,递归遍历该线程组中所有的子组,此方法主要用于调试和监视目的B0x28资讯网——每日最新资讯28at.com

public int activeGroupCount ()B0x28资讯网——每日最新资讯28at.com

返回此线程组及其子组中活动组的数目的估计值。递归遍历该线程组中的所有子群,此方法主要用于调试和监视目的B0x28资讯网——每日最新资讯28at.com

public final void checkAccess()B0x28资讯网——每日最新资讯28at.com

确定当前运行的线程是否具有修改此线程组的权限B0x28资讯网——每日最新资讯28at.com

public int enumerate(Thread[] list)B0x28资讯网——每日最新资讯28at.com

将这个线程组复制到它所在的组及其子组中B0x28资讯网——每日最新资讯28at.com

public final void destroy()B0x28资讯网——每日最新资讯28at.com

销毁此线程组及其所有子组,当线程组还要子线程或者子线程组,会抛异常B0x28资讯网——每日最新资讯28at.com

public boolean isDestroyed()B0x28资讯网——每日最新资讯28at.com

测试此线程组是否已被销毁B0x28资讯网——每日最新资讯28at.com

public final int getMaxPriority()B0x28资讯网——每日最新资讯28at.com

返回此线程组的最大优先级B0x28资讯网——每日最新资讯28at.com

public final void setMaxPriority(int pri)B0x28资讯网——每日最新资讯28at.com

设置组的最大优先级。线程组中具有较高优先级的线程不会受到影响B0x28资讯网——每日最新资讯28at.com

public final boolean isDaemon()B0x28资讯网——每日最新资讯28at.com

测试此线程组是否是守护线程组B0x28资讯网——每日最新资讯28at.com

public final void setDaemon(boolean daemon)B0x28资讯网——每日最新资讯28at.com

修改此线程组的守护进程状态B0x28资讯网——每日最新资讯28at.com

public final void interrupt()B0x28资讯网——每日最新资讯28at.com

尝试中断此线程组中的所有线程B0x28资讯网——每日最新资讯28at.com

public void list()B0x28资讯网——每日最新资讯28at.com

将此线程组的信息打印到标准输出。此方法仅用于调试B0x28资讯网——每日最新资讯28at.com

下面我们抽取几个比较常见的方法,进行演示介绍。B0x28资讯网——每日最新资讯28at.com

3.2.1、activeCount 方法

activeCount()方法用于返回此线程组及其子组中活动线程的数量的估计值,因为线程的数量是动态发生变化的,返回的值只是一个估计值。B0x28资讯网——每日最新资讯28at.com

我们看一个简单的例子就知道了。B0x28资讯网——每日最新资讯28at.com

public class MyThread extends Thread{    public MyThread(ThreadGroup group, String name) {        super(group, name);    }    @Override    public void run() {        try {            Thread.sleep(500);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
public class MyThreadMainTest {    public static void main(String[] args) throws Exception {        ThreadGroup tg = new ThreadGroup("group1");        MyThread t1 = new MyThread (tg, "t1");        MyThread t2 = new MyThread (tg, "t2");        t1.start();        t2.start();        System.out.println("线程组的名称:" +  tg.getName() + ",活动的线程数:" +  tg.activeCount());        Thread.sleep(1000);        System.out.println("线程组的名称:" +  tg.getName() + ",活动的线程数:" +  tg.activeCount());    }}

输出结果如下:B0x28资讯网——每日最新资讯28at.com

线程组的名称:group1,活动的线程数:2线程组的名称:group1,活动的线程数:0

第一次检查线程都处于运行状态,因此活动的线程数为 2;过 1 秒之后,线程运行结束,活动的线程数为 0。B0x28资讯网——每日最新资讯28at.com

3.2.2、isDaemon 方法

setDaemon()方法用于测试此线程组是否是守护线程组。B0x28资讯网——每日最新资讯28at.com

需要注意的是:后台线程组和后台线程是两个概念,后台线程组的特性是最后一个线程执行完或最后一个线程被销毁时,后台线程组自动销毁,线程组只是为了统一管理线程的一个方式,跟后台线程有区别!B0x28资讯网——每日最新资讯28at.com

例子如下:B0x28资讯网——每日最新资讯28at.com

public class MyThread extends Thread{    public MyThread(ThreadGroup group, String name) {        super(group, name);    }    @Override    public void run() {        System.out.println("当前线程:" + Thread.currentThread().getName() + ",是否后台线程:" +  Thread.currentThread().isDaemon());        System.out.println("当前线程组:" + Thread.currentThread().getThreadGroup().getName() + ",是否后台线程组:" +  Thread.currentThread().getThreadGroup().isDaemon());    }}
public class MyThreadMainTest4 {    public static void main(String[] args) throws Exception {        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();        new MyThread(mainGroup, "t1").start();        Thread.sleep(100);        // 设置守护线程组        ThreadGroup tg = new ThreadGroup("group1");        tg.setDaemon(true);        new MyThread(tg,"t2").start();    }}

输出结果如下:B0x28资讯网——每日最新资讯28at.com

当前线程:t1,是否后台线程:false当前线程组:main,是否后台线程组:false当前线程:t2,是否后台线程:false当前线程组:group1,是否后台线程组:true
3.2.3、interrupt 方法

interrupt()方法用于尝试中断此线程组中的所有线程。如果正在运行的线程没有进入阻塞,是无法中断的。B0x28资讯网——每日最新资讯28at.com

例子如下:B0x28资讯网——每日最新资讯28at.com

public class MyThreadA extends Thread{    public MyThreadA(ThreadGroup group, String name) {        super(group, name);    }    @Override    public void run() {        System.out.println("线程:" + Thread.currentThread().getName() + ",开始运行");        String t;        for (int i = 0; i < 1000000000; i++) {            t = i + "";        }        System.out.println("线程:" + Thread.currentThread().getName() + ",停止运行");    }}
public class MyThreadB extends Thread{    public MyThreadB(ThreadGroup group, String name) {        super(group, name);    }    @Override    public void run() {        System.out.println("线程:" + Thread.currentThread().getName() + ",开始运行");        while (!Thread.interrupted()){        }        System.out.println("线程:" + Thread.currentThread().getName() + ",停止运行");    }}
public class MyThreadC extends Thread{    public MyThreadC(ThreadGroup group, String name) {        super(group, name);    }    @Override    public void run() {        System.out.println("线程:" + Thread.currentThread().getName() + ",开始运行");        try {            Thread.sleep(1000);        } catch (Exception e){//            e.printStackTrace();        }        System.out.println("线程:" + Thread.currentThread().getName() + ",停止运行");    }}
public class MyThreadMainTest {    public static void main(String[] args) throws Exception {        ThreadGroup tg = new ThreadGroup("group1");        new MyThreadA(tg,"t1").start();        new MyThreadB(tg,"t2").start();        new MyThreadC(tg,"t3").start();        // 尝试中断线程组里面的线程        tg.interrupt();    }}

输出结果如下:B0x28资讯网——每日最新资讯28at.com

线程:t1,开始运行线程:t2,开始运行线程:t2,停止运行线程:t3,开始运行线程:t3,停止运行

线程t1只有等它运行结束,通过interrupt()不能中断程序!B0x28资讯网——每日最新资讯28at.com

四、小结

本文主要围绕线程组的一些基本概念以及常用方法,并结合了一些简单示例进行介绍。B0x28资讯网——每日最新资讯28at.com

线程组的出现更多的是便于有组织的管理线程,比如 Java 的线程池就用到了线程组,更多的线程知识,我们在后续的文章中会进行介绍。B0x28资讯网——每日最新资讯28at.com

如果有描述不对的地方,欢迎网友留言指出。B0x28资讯网——每日最新资讯28at.com

五、参考

1、https://www.cnblogs.com/xrq730/p/4856072.htmlB0x28资讯网——每日最新资讯28at.com

2、https://cloud.tencent.com/developer/article/1633465B0x28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-41695-0.html什么是线程组?你学会了吗?

声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。

显示全文

上一篇:Go未来演进:基于共同目标和数据驱动的决策

下一篇:利用Apache Kafka、Flink和Druid构建实时数据架构

最新热点