【线程】ThreadGroup 实战与剖析 (十七)

我的原则:先会用再说,内部慢慢来。
学以致用,根据场景学源码


一、前言

1.1 架构

在这里插入图片描述

在这里插入图片描述
=== 点击查看top目录 ===

1.2 ThreadGroup 能干嘛?
  1. 能用来操作group下面的所有线程,比如全部打断 interrupt
  2. 可以进行链路监控,例如监控某个 group 下面,当前存在多少活跃线程数目。
  3. 统一捕获该group下线程抛出的异常。
1.3 ThreadGroup 常用的方法
方法 描述
int activeCount() 查看组内部 thread 活跃数量(包括子group)
int activeGroupCount() 查看组内部 group 活跃数量(包括子group)
void list() 打印出group下的所有线程信息(包括子group)
void destroy() 摧毁线程(包括子group)
boolean isDestroyed() 查看该 group 有没有被摧毁
int enumerate(Thread[] list) copy 某个group 下面的活跃 thread
ThreadGroup getParent() 找爸爸
void interrupt() 打断这个 group 下面的所有 thread
boolean isDaemon() 看下是否是幽灵线程
void setDaemon(boolean daemon) 设置幽灵线程

二、实战

2.1 实战一 :验证 Count
  • 本demo验证了activeCount、activeGroupCount、list、getParent、interrupt 等一系列方法
  • 代码流程如下:
  1. 创建 group1
  2. group1 先创建thread1,2,3 ,由于没start,activeCount得到的的结果是 0
  3. thread1,2,3 启动起来(暂时不关闭),activeCount得到的的结果是 3
  4. 插入 thread4, 启动起来,activeCount得到的的结果是 4
  5. thread4 线程跑完,activeCount得到的的结果是 3
  6. 创建group2(传入 group1)
  7. 打印出 group2,group1,还有顶级 main 的list信息
  8. interrupt 测试打断,诶,虽然main线程跑到最后了,打那是发现scanner.nextLine() 由于内部的死循环while,无法被打断。
public static void testGroupListAndSize() throws Exception {
    
        ThreadGroup group1 = new ThreadGroup("Group1");

        Thread t1 = new Thread(group1, () -> {
    
            try {
    
                Scanner sc = new Scanner(System.in);
                System.out.println("点击任意键唤醒线程 ...");
                sc.nextLine();
            } catch (Exception e) {
    
                System.out.println("t1 被打断啦 ...");
            }
        });
        Thread t2 = new Thread(group1, () -> {
    
            try {
    
                Scanner sc = new Scanner(System.in);
                System.out.println("点击任意键唤醒线程 ...");
                sc.nextLine();
            } catch (Exception e) {
    
                System.out.println("t2 被打断啦 ...");
            }

        });
        Thread t3 = new Thread(group1, () -> {
    
            try {
    
                Scanner sc = new Scanner(System.in);
                System.out.println("点击任意键唤醒线程 ...");
                sc.nextLine();
            } catch (Exception e) {
    
                System.out.println("t3 被打断啦 ...");
            }
        });
        /*
            1. 线程未启动,未注册到 group 里面去
         */
        group1.list();
        System.out.println("group1.size ->  " + group1.activeCount());

        Thread.sleep(1000);
        System.out.println("----");

        /*
            2. 启动线程
         */
        t1.start();
        t2.start();
        t3.start();
        Thread.sleep(1000);
        group1.list();
        System.out.println("group1.size ->  " + group1.activeCount());
        System.out.println("----");
        System.out.println("==== 启动 thread4,验证 activeCount 含义(只返回活跃数量) ====");

        /*
            启动 thread4,验证 activeCount 含义(只返回活跃数量)
         */
        Thread t4 = new Thread(group1, () -> {
    
            try {
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
                System.out.println("t4 被打断啦 ...");
            }
        });
        t4.start();
        group1.list();
        System.out.println("group1.size ->  " + group1.activeCount());
        System.out.println("----");
        Thread.sleep(2000);
        System.out.println(" === 2s 后 ,t4 已经down ===");
        group1.list();
        System.out.println("group1.size ->  " + group1.activeCount());
        System.out.println("----");

        Thread.sleep(1000);
        System.out.println("==== 创建子group ====");
        ThreadGroup group2 = new ThreadGroup(group1,"Group2");
        Thread t21 = new Thread(group2, () -> {
    
            try {
    
                Scanner sc = new Scanner(System.in);
                System.out.println("点击任意键唤醒线程 ...");
                sc.nextLine();
            } catch (Exception e) {
    
                System.out.println("t21 被打断啦 ...");
            }
        });
        t21.start();
        Thread.sleep(1000);
        System.out.println("遍历下 group1 ,观察是否加入了...");
        group1.list();
        System.out.println("遍历下 group2 ...");
        group2.list();
        System.out.println("最后遍历下最牛逼的 group-main ...");
        Thread.currentThread().getThreadGroup().list();

        Thread.sleep(1000);
        /*
            interrupt
         */
        System.out.println("=== 最后打断全部线程 ===");
//        group1.destroy();
        group1.interrupt();
        /*
            sc.nextLine(); 太牛逼了,里面有死循环,听不到外面的打断
         */
        System.out.println("main thread end ...");
    }
  • 输出:
java.lang.ThreadGroup[name=Group1,maxpri=10]
group1.size ->  0
---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值