ThreadGroup线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。 
线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。 
允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。

API
构造方法 
public ThreadGroup(String name) 
    构造一个新线程组。新线程组的父线程组是目前正在运行线程的线程组。 
    不使用任何参数调用父线程组的 checkAccess 方法;这可能导致一个安全性异常。 
    参数: 
        name - 新线程组的名称。 
    抛出: 
        SecurityException - 如果当前线程不能在指定的线程组中创建线程。 
public ThreadGroup(ThreadGroup parent,String name) 
    创建一个新线程组。新线程组的父线程组是指定的线程组。 
    不使用任何参数调用父线程组的 checkAccess 方法;这可能导致一个安全性异常。 
    参数: 
        parent - 父线程组。 
        name - 新线程组的名称。 
    抛出: 
        NullPointerException - 如果线程组参数为 null。 
        SecurityException - 如果当前线程不能在指定的线程组中创建线程。

public int activeCount()

用于返回线程组中活动线程数量的上限值。

public int enumerate(Thread [] list)

用于获得对该线程组每个活动线程的引用。你可以使用activeCount方法来获得该线程组的上限值;本方法将返回放入该数组的线程数量。如果该数组太短(假设调用activeCount后可以产生更多的线程),那么可以根据需要插入任意多的线程。

参数:list  可以填入线程引用的数组

在Java中每个线程都属于某个线程组(ThreadGroup)。 
例如,如果在main()中产生一个线程,则这个线程属于main线程组(其名字为"main")管理的一员,您可以使用下面的指令来获得目前线程所属的线程组名称: 
Thread.currentThread().getThreadGroup().getName(); 
  每一个线程产生时,都会被归入某个线程组,视线程是在哪个线程组中产生而定。如果没有指定,则归入产生该子线程的线程的线程组中。 
您也可以自行指定线程组,线程一旦归入某个组,就无法更换组。 
java.lang.ThreadGroup类正如其名,可以统一管理整个线程组中的线程,您可以使用以下方式来产生线程组,而且一并指定其线程组: 
ThreadGroup threadGroup1 = new ThreadGroup("group1"); 
ThreadGroup threadGroup2 = new ThreadGroup("group2"); 
Thread thread1 =new Thread(threadGroup1, "group1's member"); 
Thread thread2 =new Thread(threadGroup2, "group2's member"); 
ThreadGroup中的某些方法,可以对所有的线程产生作用,例如interrupt()方法可以interrupt线程组中所有的线程, 
setMaxPriority()方法可以设置线程组中线程所能拥有的最高优先权(本来就拥有更高优先权的线程不受影响)。 
如果您想要一次获得线程组中所有的线程来进行某种操作,可以使用enumerate()方法,例如: 
Thread[] threads = new Thread[threadGroup1.activeCount()]; 
threadGroup1.enumerate(threads); 
activeCount()方法获得线程组中正在运行的线程数量,enumerate()方法要传入一个Thread数组, 
它将线程对象设置到每个数组字段中,然后就可以通过数组索引来操作这些线程。 
ThreadGroup中有一个uncaughtException()方法。当线程组中某个线程发生Unchecked exception异常时, 
由执行环境调用此方法进行相关处理,如果有必要,您可以重新定义此方法,直接使用范例15.9来示范如何实现。
范例1 
ThreadGroupDemo.java文件 
    package onlyfun.caterpillar; 
    import java.io.*; 
    public class ThreadGroupDemo { 
    public static void main(String[] args) { 
    ThreadGroup threadGroup1 = 
    // 这是匿名类写法 
    new ThreadGroup("group1") { 
    // 继承ThreadGroup并重新定义以下方法 
    // 在线程成员抛出unchecked exception 
    // 会执行此方法 
    public void uncaughtException(Thread t, Throwable e) { 
    System.out.println(t.getName() + ": " 
    + e.getMessage()); 
    } 
    }; 
    // 这是匿名类写法 
    Thread thread1 = 
    // 这个线程是threadGroup1的一员 
    new Thread(threadGroup1, 
    new Runnable() { 
    public void run() { 
    // 抛出unchecked异常 
    throw new RuntimeException("测试异常"); 
    } 
    }); 
    
            thread1.start(); 
    } 
    } 
  在uncaughtException()方法的参数中,第一个参数可以获得发生异常的线程实例,而第二个参数可以获得异常对象, 
范例中显示了线程的名称及异常信息,结果如下所示: 
Thread-0: 测试异常 
在J2SE 5.0之前,如果要统一处理某些线程的Unchecked Exception,可以使用ThreadGroup来管理。 
在继承ThreadGroup之后重新定义其uncaughtException()方法,就如范例1所示。在J2SE 5.0之后,就不用这么麻烦, 
可以让异常处理类使用Thread.UncaughtExceptionHandler接口,并实现其 uncaughtException()方法, 
例如可以改写范例1,首先定义一个类让其实现 Thread.UncaughtExceptionHandler接口。 
范例2 
ThreadExceptionHandler.java文件 
package onlyfun.caterpillar; 
public class ThreadExceptionHandler 
implements Thread.UncaughtExceptionHandler { 
public void uncaughtException(Thread t, Throwable e) { 
System.out.println(t.getName() + ": " 
+ e.getMessage()); 


接着范例1主流程可以改写为范例3。 
范例3 ThreadGroupDemo2.java 
    package onlyfun.caterpillar; 
    import java.io.*; 
    public class ThreadGroupDemo2 { 
    public static void main(String[] args) { 
    // 建立异常处理者 
    ThreadExceptionHandler handler = 
    new ThreadExceptionHandler(); 
    ThreadGroup threadGroup1 = new ThreadGroup("group1"); 
    // 这是匿名类写法 
    Thread thread1 = 
    // 这个线程是threadGroup1的一员 
    new Thread(threadGroup1, 
    new Runnable() { 
    public void run() { 
    // 抛出unchecked异常 
    throw new RuntimeException("测试异常"); 
    } 
    }); 
    // 设置异常处理者 
    thread1.setUncaughtExceptionHandler(handler); 
    thread1.start(); 
    } 
    } 
需要注意的函数: 
public final void checkAccess() 
    确定当前运行的线程是否有权修改此线程组。 
    如果有安全管理器,则用此线程组作为其参数调用 checkAccess 方法。结果可能是抛出一个 SecurityException。 
    抛出: 
        SecurityException - 如果不允许当前线程访问此线程组。 
注意:它返回的居然是void,而不是boolean.其实如果当前运行的线程没有权修改此线程组,则抛出一个 SecurityException。 
否则不抛出。 
public int enumerate(Thread[] list) 
    把此线程组及其子组中的所有活动线程复制到指定数组中。 
    首先,不使用任何参数调用此线程组的 checkAccess 方法;这可能导致一个安全性异常。 
    应用程序可以使用 activeCount 方法获取数组大小的估计数,但是,如果数组太小而无法保持所有线程,则忽略额外的线程。如果获得此线程组及其子组中的所有活动线程非常重要,则调用方应该验证返回的 int 值是否严格小于 list 的长度。 
    由于使用此方法所固有的竞争条件,建议只将此方法用于信息目的。 
    参数: 
        list - 放置线程列表的数组。 
    返回: 
        放入数组中的线程数。 
    抛出: 
        SecurityException - 如果不允许当前线程枚举此线程组。 
注意:它的目的是把子组中的所有活动线程复制到指定数组list中。还有一些enumerate的函数,具体参考文档。 
public final void interrupt() 
    中断此线程组中的所有线程。 
    首先,不使用任何参数调用此线程组的 checkAccess 方法;这可能导致一个安全性异常。 
    然后,此方法将对此线程组及其所有子组中的所有线程调用 interrupt 方法。 
    抛出: 
        SecurityException - 如果不允许当前线程访问此线程组或线程组中的任何线程

class ThreadGroupDemo
{
class WorkThread{
boolean stop;
public WorkThread(ThreadGroup t,String threadName){
super(t,threadName);
stop = false;
}
public void run() {
System.out.println(Thread.currentThread().getName() + " starting.");
try {
for (int i = 1; i < 1000; i++) {
System.out.print(".");
Thread.sleep(250);
synchronized (this) {
if (stopped)
break;
}
}
} catch (Exception exc) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
System.out.println(Thread.currentThread().getName() + " exiting.");
} synchronized void myStop() {
stopped = true;
}
} public class Main {
public static void main(String args[]) throws Exception {
ThreadGroup tg = new ThreadGroup("My Group"); WorkThread thrd = new WorkThread(tg, "aaaa);
WorkThread thrd2 = new WorkThread(tg, "bbbb");
WorkThread thrd3 = new WorkThread(tg, "cccc"); thrd.start();
thrd2.start();
thrd3.start(); Thread.sleep(1000); System.out.println(tg.activeCount() + " threads in thread group."); WorkThread thrds[] = new WorkThread [tg.activeCount()];
tg.enumerate(thrds); //用于获得该线程组中每个活动线程的引用。参数list是用来填入线程应用的数组
for (WorkThread t : thrds){
System.out.println(t.getName()); if(t.isActive()&&"bbbb".equal(t.getName))thrd.myStop();
}
Thread.sleep(1000); System.out.println(tg.activeCount() + " threads in tg.");
tg.interrupt();
}
}

线程组ThreadGroup的更多相关文章

  1. 线程组ThreadGroup分析详解 多线程中篇(三)

    线程组,顾名思义,就是线程的组,逻辑类似项目组,用于管理项目成员,线程组就是用来管理线程. 每个线程都会有一个线程组,如果没有设置将会有些默认的初始化设置 而在java中线程组则是使用类ThreadG ...

  2. “全栈2019”Java多线程第十三章:线程组ThreadGroup详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. JDK中线程组ThreadGroup

    如果线程有100条...分散的不好管理... 线程同样可以分组ThreadGroup类. 线程组表示一个线程的集合.此外,线程组也可以包含其他线程组.线程组构成一棵树,在树中,除了初始线程组外,每个线 ...

  4. 多线程 线程组 ThreadGroup

    package org.zln.thread; import java.util.Date; /** * Created by sherry on 000024/6/24 22:30. */ publ ...

  5. 浅析Java中线程组(ThreadGroup类)

    Java中使用ThreadGroup类来代表线程组,表示一组线程的集合,可以对一批线程和线程组进行管理.可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的 ...

  6. java 多线程 线程组ThreadGroup;多线程的异常处理。interrupt批量停止组内线程;线程组异常处理

    1,线程组定义: 线程组存在的意义,首要原因是安全.java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的.但如果在不同的线程组中,那么就不能"跨线程组&q ...

  7. 16.ThreadGroup线程组

    public class ThreadGroupDemo implements Runnable{ public static void main(String[] args){ //建立一个名为&q ...

  8. 0039 Java学习笔记-多线程-线程控制、线程组

    join线程 假如A线程要B线程去完成一项任务,在B线程完成返回之前,不进行下一步执行,那么就可以调用B线程的join()方法 join()方法的重载: join():等待不限时间 join(long ...

  9. JAVA基础知识之多线程——线程组和未处理异常

    线程组 Java中的ThreadGroup类表示线程组,在创建新线程时,可以通过构造函数Thread(group...)来指定线程组. 线程组具有以下特征 如果没有显式指定线程组,则新线程属于默认线程 ...

随机推荐

  1. C++中几个值得分析的小问题(2)

    下面有3个小问题,作为C++ Beginner你一定要知道错在哪里了. 1.派生类到基类的引用或指针转换一定“完美”存在? 一般情况,你很可能会认为:派生类对象的引用或指针转换为基类对象的引用或指针是 ...

  2. WiFi无线网络参数 802.11a/b/g/n 详解

    转载自:WiFi无线网络参数 802.11a/b/g/n 详解 如转载侵犯您的版权,请联系:2378264731@qq.com 802.11a/b/g/n,其实指的是无线网络协议,细分为802.11a ...

  3. Eclipse快捷键详细解析

    android开发中常用的Eclipse快捷键详细解析 1.查看快捷键定义的地方 Window->Preferences->General->Keys. 2.更改启动页 在Andro ...

  4. 前端神器!!gulp livereload实现浏览器自动刷新

    首先gulp是基于Node的,所以确保你已经安装 node.js,在Nodejs官方网站下载跟自己操作系统相对应的安装包. 先说一下gulp安装流程: 1:全局安装gulp,操作为: npm inst ...

  5. Android常见问题——Genymotion无法启动问题

    在官网下载了Genymotion和VirturalBox的合集安装之后启动模拟器的时候发现启动不了(默认下载,啥都没干),在网上找了一些方法,也没有解决,最后偶然看到一种方法才解决的,先看一下具体的问 ...

  6. TCP、UDP详解

    OSI 计算机网络7层模型 TCP/IP四层网络模型 传输层提供应用间的逻辑通信(端到端),网络层提供的是主机到主机的通信,传输层提供的是可靠服务. TCP 中常说的握手指的是:连接的定义和连接的建立 ...

  7. UNIX环境高级编程 标准IO库

    标准I/O库处理很多细节,使得便于用户使用. 流和 FILE 对象 对于标准I/O库,操作是围绕 流(stream)进行的.当用标准I/O打开或创建一个文件时,我们已使一个流与一个文件相关联. 对于A ...

  8. js之购物车案例

      这里主要提供思路: 一共两个页面通过原生来实现,我们需要对cookie进行封装. 在商品列表页,我们将点击添加的商品放入一个对象中,而后将该对象放入数组中,一个对象可以说就是一个商品.在购物车页面 ...

  9. [转](阿里笔试)使用多线程和sleep函数生成字符串的伪随机排列

    http://blog.csdn.net/jiaowopan/article/details/12009079 C/C++(Linux平台) 注意编译连接时需要链接pthread库,即g++ XX.c ...

  10. Java并发--并发容器之ConcurrentHashMap

    下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为 ...