当前位置:首页 > 科技  > 软件

什么是线程组?你学会了吗?

来源: 责编: 时间:2023-12-11 09:26:47 280观看
导读一、简介在之前的多线程系列文章中,我们陆陆续续的介绍了Thread线程类相关的知识和用法,其实在Thread类上还有一层ThreadGroup类,也就是线程组。今天我们就一起来简单的聊聊线程组相关的知识和用法。二、什么是线程组线

一、简介

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

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

二、什么是线程组

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

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

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

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

比如,我们通常创建的main方法,对应的是main线程,它所属的是main线程组,main线程组的父级是是system系统线程组。q0O28资讯网——每日最新资讯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());}

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

currentThread:maincurrentThreadGroup:mainsystemThreadGroup:system

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

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

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

三、线程组用法详解

3.1、构造方法介绍

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

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

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

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

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

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

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

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

下面,我们演示一下这两个构造函数的用法:q0O28资讯网——每日最新资讯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());}

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

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

3.2、核心方法介绍

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3.2.1、activeCount 方法

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

我们看一个简单的例子就知道了。q0O28资讯网——每日最新资讯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());    }}

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

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

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

3.2.2、isDaemon 方法

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

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

例子如下:q0O28资讯网——每日最新资讯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();    }}

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

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

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

例子如下:q0O28资讯网——每日最新资讯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();    }}

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

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

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

四、小结

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

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

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

五、参考

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

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

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

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

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

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

标签:
  • 热门焦点
  • vivo TWS Air开箱体验:真轻 臻好听

    在vivo S15系列新机的发布会上,vivo的最新款真无线蓝牙耳机vivo TWS Air也一同发布,本次就这款耳机新品给大家带来一个简单的分享。外包装盒上,vivo TWS Air保持了vivo自家产
  • 太卷!Redmi MAX 100英寸电视便宜了:12999元买Redmi史上最大屏

    8月5日消息,从小米商城了解到,Redmi MAX 100英寸巨屏电视日前迎来官方优惠,到手价12999元,比发布价便宜了7000元,在大屏电视市场开卷。据了解,Redmi MAX 100
  • 多线程开发带来的问题与解决方法

    使用多线程主要会带来以下几个问题:(一)线程安全问题  线程安全问题指的是在某一线程从开始访问到结束访问某一数据期间,该数据被其他的线程所修改,那么对于当前线程而言,该线程
  • 一篇文章带你了解 CSS 属性选择器

    属性选择器对带有指定属性的 HTML 元素设置样式。可以为拥有指定属性的 HTML 元素设置样式,而不仅限于 class 和 id 属性。一、了解属性选择器CSS属性选择器提供了一种简单而
  • 腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • 阿里大调整

    来源:产品刘有媒体报道称,近期淘宝天猫集团启动了近年来最大的人力制度改革,涉及员工绩效、层级体系等多个核心事项,目前已形成一个初步的&ldquo;征求意见版&rdquo;:1、取消P序列
  • 网传小米汽车开始筛选交付中心 建筑面积不低于3000平方米

    7月7日消息,近日有微博网友@长三角行健者爆料称,据经销商集团反馈,小米汽车目前已经开始了交付中心的筛选工作,要求候选场地至少有120个车位,建筑不能低
  • 机构称Q2全球智能手机出货量同比下滑11% 苹果份额依旧第2

    7月20日消息,据外媒报道,研究机构的报告显示,由于需求下滑,今年二季度全球智能手机的出货量,同比下滑了11%,三星、苹果等主要厂商的销量,较去年同期均有下
  • 电博会上海尔智家模拟500平大平层,还原生活空间沉浸式体验

    电博会为了更好地让参展观众真正感受到智能家居的绝妙之处,海尔智家的程传岭先生同样介绍了展会上海尔智家的模拟500平大平层,还原生活空间沉浸式体验。程传
Top