ThreadGroup线程组

2023-01-09 09:27:22

ThreadGroup简介
顾名思义,线程组是多个线程的集合,可以对一批线程或线程组进行统一管理,比如中断interrupt(),destroy()。另外可以准确的定位到某个线程和进行统一的异常捕获。一个线程组中可以有线程,也可以有线程组,所以线程组的结构有点类似于树,如下所示

 下面通过代码来看,线程组的树形结构

    public static void main(String[] args) {
        ThreadGroup tg = new ThreadGroup("tg");
        while(tg.getParent() != null){
            tg = tg.getParent();
        }
        tg.list();
    }

运行结果如下:
java.lang.ThreadGroup[name=system,maxpri=10]
    Thread[Reference Handler,10,system]
    Thread[Finalizer,8,system]
    Thread[Signal Dispatcher,9,system]
    Thread[Attach Listener,5,system]
    java.lang.ThreadGroup[name=main,maxpri=10]
        Thread[main,5,main]
        Thread[Monitor Ctrl-Break,5,main]
        java.lang.ThreadGroup[name=tg,maxpri=10]

ThreadGroup属性与构造方法

    private final ThreadGroup parent;  // 父线程组
    String name; // 线程组名称
    int maxPriority; // 最大优先级,线程组中的线程优先级不能高于此
    boolean destroyed; // 是否被销毁
    boolean daemon; // 是否守护线程
    boolean vmAllowSuspension; //是否可以中断

    int nUnstartedThreads = 0; // 未启动的线程
    int nthreads; // ThreadGroup中线程数目
    Thread threads[]; // ThreadGroup中的线程

    int ngroups; // 线程组数目
    ThreadGroup groups[]; // 线程组数组

    // 最顶层线程组
    private ThreadGroup() { 
        this.name = "system";
        this.maxPriority = Thread.MAX_PRIORITY;
        this.parent = null;
    }

    // 如果没有指定线程组,默认以当前线程所在线程组为父线程组
    public ThreadGroup(String name) {
        this(Thread.currentThread().getThreadGroup(), name);
    }

    // 指定父线程组
    public ThreadGroup(ThreadGroup parent, String name) {
        // checkParentAccess检查当前线程是否有权限修改parent线程组
        this(checkParentAccess(parent), parent, name);
    }

    private ThreadGroup(Void unused, ThreadGroup parent, String name) {
        this.name = name;
        this.maxPriority = parent.maxPriority;
        this.daemon = parent.daemon;
        this.vmAllowSuspension = parent.vmAllowSuspension;
        this.parent = parent;
        parent.add(this); // 添加当前线程组到父线程组,如果父线程组存放线程组数组已满,则2倍扩容
    }

 ThreadGroup Api如下(过时方法未列出)

int activeCount()    //返回此线程组及其子组中活动线程数的估计
int activeGroupCount()  //返回此线程组及其子组中活动组数的估计
void checkAccess()    //确定当前运行的线程是否有权限修改此线程组
void destroy()   //销毁此线程组及其所有子组
int enumerate(Thread[] list)    //将此线程组及其子组中的每个活动线程复制到指定的数组中
int enumerate(Thread[] list, boolean recurse)    //将此线程组中的每个活动线程复制到指定的数组中
int getMaxPriority()    //返回此线程组的最大优先级
String getName()    //返回此线程组的名称
ThreadGroup getParent()    //返回此线程组的父级
void interrupt()    //中断此线程组中的所有线程
boolean isDaemon()    //测试此线程组是否是守护线程组
boolean isDestroyed()    //测试此线程组是否已被破坏
void list()    //将有关此线程组的信息打印到标准输出。
boolean parentOf(ThreadGroup g)    //测试此线程组是线程组参数还是其祖先线程组之一
void setDaemon(boolean daemon)    //更改此线程组的守护程序状态
void setMaxPriority(int pri)    //设置组的最大优先级
String toString()    //返回此Thread组的字符串表示形式
void uncaughtException(Thread t, Throwable e)    //当该线程组中的线程由于未捕获的异常而停止时,由Java虚拟机调用,并且该线程没有特定的Thread.UncaughtExceptionHandler设置

线程组的异常处理

        ThreadGroup group = new ThreadGroup("group") {
            @Override
            public void uncaughtException(Thread thread, Throwable throwable) {
                System.out.println(thread.getName() +":"+ throwable.getMessage());
            }
        };
        Thread thread = new Thread(group, new Runnable() {
            @Override
            public void run() {
                throw new RuntimeException("线程内部抛出异常");
            }
        });
        thread.start();

        // 上述group如果眉头重写uncaughtException,则直接往外抛出,
        // 重写后抛出异常则会调用uncaughtException进行处理,前提当然是thread是group下的线程。


        ThreadGroup group = new ThreadGroup("group") {
            @Override
            public void uncaughtException(Thread thread, Throwable throwable) {
                System.out.println("enter ThreadGroup uncaughtException: " + thread.getName() + "#" + throwable.getMessage());
            }
        };
        Thread thread0 = new Thread(group, new Runnable() {
            @Override
            public void run() {
                throw new RuntimeException("线程内部抛异常0");
            }
        });
        Thread thread1 = new Thread(group, new Runnable() {
            @Override
            public void run() {
                throw new RuntimeException("线程内部抛异常1");
            }
        });
        thread0.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("enter UncaughtExceptionHandler uncaughtException: " + t.getName() + "#" + e.getMessage());
            }
        });
        thread0.start();
        thread1.start();
        // 线程内部抛出异常捕获优先级顺序:UncaughtExceptionHandler.uncaughtException > ThreadGroup.uncaughtException

 

  • 作者:黑洞刺客
  • 原文链接:https://blog.csdn.net/jiangtianjiao/article/details/104011226
    更新时间:2023-01-09 09:27:22