线程组-概念及其关键性 (线程组的作用)
一、简介
在之前的多线程系列文章中,咱们陆陆续续的引见了线程类相关的常识和用法,其真实类上还有一层
ThreadGroup
类,也就是线程组。
当天咱们就一同来繁难的聊聊 线程组 相关的常识和用法。
二、什么是线程组
线程组,繁难来说就是多个线程的汇合,它的出现关键是为了更繁难的治理线程。
从结构角度看,线程组与线程之间其实是一个父子结构,一个线程组可以领有几个线程,同时也可以领有几个线程组。整个组织结构像一棵树一样,每个线程必定有一个线程组,线程组或许又有一个父线程组,追溯到根节点就是一个系统线程组。
线程组与线程之间的相关,可以用如下图来形容。
比如,咱们理论创立的方法,对应的是线程,它所属的是线程组,线程组的父级是是系统线程组。
publicstaticvoidmain(String[]args){ThreadcurrentThread=Thread.currentThread();ThreadGroupcurrentThreadGroup=currentThread.getThreadGroup();ThreadGroupsystemThreadGroup=currentThreadGroup.getParent();System.out.println("currentThread:"+currentThread.getName());System.out.println("currentThreadGroup:"+currentThreadGroup.getName());System.out.println("systemThreadGroup:"+systemThreadGroup.getName());}
输入结果如下:
currentThread:maincurrentThreadGroup:mainsystemThreadGroup:system
其中线程组就是根节点,再上一层就没有了,假设调用会抛空指针意外。
线程组最关键的作用是:可以成功批量治理线程或许线程组,有效的对线程或许线程组对象启动审核、尝试终止等操作。
上方咱们就一同来看看
ThreadGroup
的罕用方法和经常使用技巧。
三、线程组用法详解
3.1、结构方法引见
ThreadGroup
提供了两个结构方法,内容如下:
方法 | 形容 |
---|---|
ThreadGroup(Stringname) | 依据线程组称号创立线程组,其父线程组为main线程组 |
ThreadGroup(ThreadGroupparent,Stringname) | 依据线程组称号创立线程组,其父线程组为指定的parent线程组 |
其中允许指定父级线程组的方法,在实践的经常使用中比拟经常出现。
上方,咱们展示一下这两个结构函数的用法:
publicstaticvoidmain(String[]args){ThreadGroupsubThreadGroup1=newThreadGroup("sub1");ThreadGroupsubThreadGroup2=newThreadGroup(subThreadGroup1,"sub2");System.out.println("sub1parentthreadgroupname:"+subThreadGroup1.getParent().getName());System.out.println("sub2parentthreadgroupname:"+subThreadGroup2.getParent().getName());}
输入结果如下:
sub1parentthreadgroupname:mainsub2parentthreadgroupname:sub1
3.2、外围方法引见
ThreadGroup
提供了很多有用的方法,上方整顿了一些方法的简明引见,内容如下:
方法 | 形容 |
---|---|
publicfinalStringgetName() | 前往此线程组的称号 |
publicfinalThreadGroupgetParent() | 前往此线程组的父级 |
publicfinalbooleanparentOf(ThreadGroupg) | 测试此线程组是线程组参数还是其父级线程组之一 |
publicintactiveCount() | 前往此线程组及其子组中优惠线程的数量的预计值,递归遍历该线程组中一切的子组,此方法关键用于调试和监督目标 |
publicintactiveGroupCount() | 前往此线程组及其子组中优惠组的数目标预计值。递归遍历该线程组中的一切子群,此方法关键用于调试和监督目标 |
publicfinalvoidcheckAccess() | 确定以后运转的线程能否具备修正此线程组的权限 |
publicintenumerate(Thread[]list) | 将这个线程组复制到它所在的组及其子组中 |
publicfinalvoiddestroy() | 销毁此线程组及其一切子组,当线程组还要子线程或许子线程组,会抛意外 |
publicbooleanisDestroyed() | 测试此线程组能否已被销毁 |
publicfinalintgetMaxPriority() | 前往此线程组的最大优先级 |
publicfinalvoidsetMaxPriority(intpri) | 设置组的最大优先级。线程组中具备较高优先级的线程不会遭到影响 |
publicfinalbooleanisDaemon() | 测试此线程组能否是守护线程组 |
publicfinalvoidsetDaemon(booleandaemon) | 修正此线程组的守护进程形态 |
publicfinalvoidinterrupt() | 尝试终止此线程组中的一切线程 |
publicvoidlist() | 将此线程组的消息打印到规范输入。此方法仅用于调试 |
上方咱们抽取几个比拟经常出现的方法,启动展示引见。
3.2.1、activeCount方法
activeCount()
方法用于前往此线程组及其子组中优惠线程的数量的预计值,由于线程的数量是灵活出现变动的,前往的值只是一个预计值。
咱们看一个繁难的例子就知道了。
publicclassMyThreadextendsThread{publicMyThread(ThreadGroupgroup,Stringname){super(group,name);}@Overridepublicvoidrun(){try{Thread.sleep(500);}catch(InterruptedExceptione){e.printStackTrace();}}}
publicclassMyThreadMainTest{publicstaticvoidmain(String[]args)throwsException{ThreadGrouptg=newThreadGroup("group1");MyThreadt1=newMyThread(tg,"t1");MyThreadt2=newMyThread(tg,"t2");t1.start();t2.start();System.out.println("线程组的称号:"+tg.getName()+",优惠的线程数:"+tg.activeCount());Thread.sleep(1000);System.out.println("线程组的称号:"+tg.getName()+",优惠的线程数:"+tg.activeCount());}}
输入结果如下:
线程组的称号:group1,优惠的线程数:2线程组的称号:group1,优惠的线程数:0
第一次性审核线程都处于运转形态,因此优惠的线程数为2;过1秒之后,线程运转完结,优惠的线程数为0。
3.2.2、isDaemon方法
setDaemon()
方法用于测试此线程组能否是守护线程组。
须要留意的是:后盾线程组和后盾线程是两个概念,后盾线程组的个性是最后一个线程口头完或最后一个线程被销毁时,后盾线程组智能销毁,线程组只是为了一致治理线程的一个方式,跟后盾线程有区别!
例子如下:
publicclassMyThreadextendsThread{publicMyThread(ThreadGroupgroup,Stringname){super(group,name);}@Overridepublicvoidrun(){System.out.println("以后线程:"+Thread.currentThread().getName()+",能否后盾线程:"+Thread.currentThread().isDaemon());System.out.println("以后线程组:"+Thread.currentThread().getThreadGroup().getName()+",能否后盾线程组:"+Thread.currentThread().getThreadGroup().isDaemon());}}
publicclassMyThreadMainTest4{publicstaticvoidmain(String[]args)throwsException{ThreadGroupmainGroup=Thread.currentThread().getThreadGroup();newMyThread(mainGroup,"t1").start();Thread.sleep(100);//设置守护线程组ThreadGrouptg=newThreadGroup("group1");tg.setDaemon(true);newMyThread(tg,"t2").start();}}
输入结果如下:
以后线程:t1,能否后盾线程:false以后线程组:main,能否后盾线程组:false以后线程:t2,能否后盾线程:false以后线程组:group1,能否后盾线程组:true
3.2.3、interrupt方法
interrupt()
方法用于尝试终止此线程组中的一切线程。假设正在运转的线程没有进入阻塞,是不可终止的。
例子如下:
publicclassMyThreadAextendsThread{publicMyThreadA(ThreadGroupgroup,Stringname){super(group,name);}@Overridepublicvoidrun(){System.out.println("线程:"+Thread.currentThread().getName()+",开局运转");Stringt;for(inti=0;i<1000000000;i++){t=i+"";}System.out.println("线程:"+Thread.currentThread().getName()+",中止运转");}}
publicclassMyThreadBextendsThread{publicMyThreadB(ThreadGroupgroup,Stringname){super(group,name);}@Overridepublicvoidrun(){System.out.println("线程:"+Thread.currentThread().getName()+",开局运转");while(!Thread.interrupted()){}System.out.println("线程:"+Thread.currentThread().getName()+",中止运转");}}
publicclassMyThreadCextendsThread{publicMyThreadC(ThreadGroupgroup,Stringname){super(group,name);}@Overridepublicvoidrun(){System.out.println("线程:"+Thread.currentThread().getName()+",开局运转");try{Thread.sleep(1000);}catch(Exceptione){//e.printStackTrace();}System.out.println("线程:"+Thread.currentThread().getName()+",中止运转");}}
publicclassMyThreadMainTest{publicstaticvoidmain(String[]args)throwsException{ThreadGrouptg=newThreadGroup("group1");newMyThreadA(tg,"t1").start();newMyThreadB(tg,"t2").start();newMyThreadC(tg,"t3").start();//尝试终止线程组外面的线程tg.interrupt();}}
输入结果如下:
线程:t1,开局运转线程:t2,开局运转线程:t2,中止运转线程:t3,开局运转线程:t3,中止运转
线程只要等它运转完结,经过
interrupt()
不能终止程序!
四、小结
本文关键围绕线程组的一些基本概念以及罕用方法,并联合了一些繁难示例启动引见。
线程组的出现更多的是便于有组织的治理线程,比如的线程池就用到了线程组,更多的线程常识,咱们在后续的文章中会启动引见。
假设无形容不对的中央,欢迎网友留言指出。
五、参考
1、
2、
java问题:什么是线程组
在Java中每一个线程都归属于某个线程组管理的一员,例如在主函数main()主工作流程中产生一个线程,则产生的线程属于main这个线程组管理的一员。 简单地说,线程组就是由线程组成的管理线程的类,这个类是类。 定义一个线程组,通过以下代码可以实现。 ThreadGroup group=new ThreadGroup(group);Thread thread=new Thread(group,the first thread of group);ThreadGroup类中的某些方法,可以对线程组中的线程产生作用。 例如,setMaxPriority()方法可以设定线程组中的所有线程拥有最大的优先权。 所有线程都隶属于一个线程组。 那可以是一个默认线程组,亦可是一个创建线程时明确指定的组。 在创建之初,线程被限制到一个组里,而且不能改变到一个不同的组。 每个应用都至少有一个线程从属于系统线程组。 若创建多个线程而不指定一个组,它们就会自动归属于系统线程组。 线程组也必须从属于其他线程组。 必须在构建器里指定新线程组从属于哪个线程组。 若在创建一个线程组的时候没有指定它的归属,则同样会自动成为系统线程组的一名属下。 因此,一个应用程序中的所有线程组最终都会将系统线程组作为自己的“父”之所以要提出“线程组”的概念,一般认为,是由于“安全”或者“保密”方面的理由。 根据Arnold和Gosling的说法:“线程组中的线程可以修改组内的其他线程,包括那些位于分层结构最深处的。 一个线程不能修改位于自己所在组或者下属组之外的任何线程”(注释①)①:《The Java Programming Language》第179页。 该书由Arnold和James Gosling编著,Addison-Wesley于1996年出版
简述进程、线程、作业的概念,并说明它们与程序的关系。
1、进程
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体。
2、线程
线程(英语:thread)是操作系统能够进行运算调度的最小单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
3、作业
在某些操作系统中,作业(job)是计算机操作者(或是一个叫做作业调度器的程序)交给操作系统的执行单位。作业是一个比程序更为广泛的概念,包含了通常的程序、数据、作业说明书。系统通过作业说明书控制文件形式的程序和数据,执行和操作,并在系统中建立作业控制块的数据结构。
扩展资料:
进程中包含的程序相关信息:
1、程序的可运行机器码的一个在存储器的映像。
2、分配到的存储器(通常包括虚拟内存的一个区域)。存储器的内容包括可运行代码、特定于进程的数据(输入、输出)、调用堆栈、堆栈(用于保存运行时运数中途产生的数据)。
3、分配给该进程的资源的操作系统描述符,诸如文件描述符(Unix术语)或文件句柄(Windows)、数据源和数据终端。
4、安全特性,诸如进程拥有者和进程的权限集(可以容许的操作)。
5、处理器状态(内文),诸如寄存器内容、物理存储器寻址等。当进程正在运行时,状态通常储存在寄存器,其他情况在存储器。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。