2023-06-14  阅读(5)
原文作者:求和的小熊猫 原文地址:https://blog.csdn.net/qq_38219153/article/details/108470258

线程组

线程组多用于对相同功能的线程进行管理,线程组既可以包含子线程,也可以包含子线程组。
线程组的最高一级是 system 线程组,即系统线程组,也是根线程组。 一般线程组呈树状结构。
因此线程组可以视为

202306142126036641.png

创建线程时的默认线程组

一般创建咸成师并没有被设置线程组入参,那么创建线程时线程会被分配到那个线程组中去呢

线程创建源码

202306142126042652.png

由源码可知,线程创建时首先判断系统是否有 securitymanager,如果有则新创建的线程会被放到和 SecurityManager 相同的线程组下,否则会和父线程在同一个线程组。

PS: Main 线程的父线程组为 System 线程组,但是System 线程组没有父线程组

如何将线程假如到线程组

那么我们该如何将线程加入到我们指定的线程组中呢
【示例】

    ThreadGroup group = new ThreadGroup("Thread-Group-1");
    Thread thread1 = new Thread(group,runnable,"Thread-1");
    thread1.start()

当创建一个新的线程组时

202306142126052103.png

202306142126060834.png

202306142126065125.png

新的线程组的默认父线程组为创建该线程组的线程所在的线程组。

线程组参数

线程组的参数:

  • name: 线程组的名称
  • maxPriority:线程组所允许的最大线程等级
  • destroyed:表示该线程组是否被销毁

线程组的常用方法

线程组的常用方法:

  • getName():获取线程组名称
  • setMaxPriority(int pri):设置线程组的最大优先级
  • getMaxPriority():获取线程组中最大的优先级
  • isDestroyed():获取线程组是否被销毁
  • enumerate(Thread list[]):将当前线程组中每一个线程以及其子线程组都复制到指定线程数组中
  • activeCount():返回当前线程组中活动的线程数目
  • interrupt():批量停止线程组中正在运行的所有线程

获取线程组与根线程组

    //获取当前线程所在的线程组名称
    Thread.currentThread().getThreadGroup().getName();
    //获取当前线程组的父线程组
    Thread.currentThread().getThreadGroup().getParent().getName();

线程组处理批量异常

当然,使用线程组也可以方便统一处理线程组中抛出的异常

Step1: 创建一个类并重写 uncaughtException 方法

    public class MyThreadGroup extends ThreadGroup {
    
    	public MyThreadGroup(String name) {
    		super(name);
    	}
    	
    	@Override
    	public void uncaughtException(Thread t,Throwable e) {
    		System.out.printf("The thread %s has thrown an Exception\n", t.getId());
    		e.printStackTrace(System.out);
    		System.out.printf("Terminating the rest of the Threads");
    		interrupt();
    	}
    
    }

Step2: 创建一个线程任务,用该任务模拟抛出异常

    public class Task implements Runnable {
    
    	@Override
    	public void run() {
    		int result;
    		Random random = new Random(Thread.currentThread().getId());
    		while(true) {
    			result = 1000/ ((int)(random.nextDouble()*100000000));
    			if(Thread.currentThread().isInterrupted()) {
    				System.out.printf("%d : Interrupted\n", Thread.currentThread().getId());
    			}
    		}
    
    	}
    
    }

Step3: Main 方法,创建多个线程并加入到线程组中,看线程组如何处理线程抛出的异常

    	public static void main(String[] args) {
    		int numberOfThreads = 2*Runtime.getRuntime().availableProcessors();
    		MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup");
    		Task task = new Task();
    		for(int i=0; i<numberOfThreads; i++) {
    			Thread t = new Thread(threadGroup,task);
    			t.start();
    		}
    		System.out.printf("Number of Threads: %d\n", threadGroup.activeCount());
    		System.out.printf("Information about the Thread Group\n");
    		threadGroup.list();
    		Thread[] threads = new Thread[threadGroup.activeCount()];
    		threadGroup.enumerate(threads);
    		for(int i=0; i<threadGroup.activeCount(); i++) {
    			System.out.printf("Thread %s: %s\n", threads[i].getName(),threads[i].getState());
    		}
    	}

Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文