1,线程组定义:

线程组存在的意义,首要原因是安全。java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的。但如果在不同的线程组中,那么就不能“跨线程组”修改数据,可以从一定程度上保证数据安全。默认情况下,我们创建的线程都在系统线程组,不过我们可以自定义自己的线程组。
线程组内部可以有线程组,组中还可以有线程,类似于下图:
0

线程组创建:

  • new ThreadGroup("test线程组")

常用方法:

  • activeGroupCount()
  • activeGroupCount()获取子线程组个数
  • enumerate(threadGroups) 将线程组内子线程,或子线程组 组复制到数组中
  • interrupt(); 批量停止线程组里面所有线程

2,线程加入线程组:

定义两个线程,然后一个线程组,分别把两个线程加入到对应的线程组
public class ThreadGroupTest {
public static void main(String[] args) {
Runnable r = () ->{
String tName = Thread.currentThread().getName();
System.out.println(tName +":运行中");
};
ThreadGroup testGroup = new ThreadGroup("test线程组");
Thread thread1 = new Thread(testGroup,r,"线程1");
Thread thread2 = new Thread(testGroup,r,"线程2");
Thread thread3 = new Thread(testGroup,r,"线程3");
thread1.start();thread2.start();thread3.start();
//查看线程组下有多少活跃线程
System.out.println(testGroup.toString() + "下活跃线程数:" + testGroup.activeCount()); //java.lang.ThreadGroup[name=test线程组,maxpri=10]下活跃线程数:3
}
}
 

3,线程组多级嵌套:线程组下面还有线程组

/**
* @ClassName ThreadGroupInThreadGroup
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/26.
*/
public class ThreadGroupInThreadGroup {
public static void main(String[] args) {
Runnable runnable = ()-> {
System.out.println(Thread.currentThread().getName() + "运行中");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
ThreadGroup parentGroup = new ThreadGroup("parent");
ThreadGroup childGroup = new ThreadGroup(parentGroup,"child");
Thread thread = new Thread(childGroup, runnable, "线程A");
Thread thread1 = new Thread(childGroup, runnable, "线程B");
Thread thread2 = new Thread(parentGroup, runnable, "线程C");
thread.start();thread1.start();thread2.start();
//常用方法
System.out.println("parentGroup 下有" + parentGroup.activeGroupCount() + "个活跃线程组"); //activeGroupCount()获取子线程组个数
ThreadGroup[] threadGroups = new ThreadGroup[parentGroup.activeGroupCount()];
parentGroup.enumerate(threadGroups); //enumerate(threadGroups) 将线程组内子线程组复制到数组中
for (ThreadGroup threadGroup:threadGroups){
System.out.println(threadGroup.getName()); //child
}
Thread[] threads = new Thread[childGroup.activeCount()];
childGroup.enumerate(threads);
for (Thread t : threads){
System.out.println("子线程组中线程:" + t.getName());
}
}
}

4、线程组的自动归属特性:

就是说我们新创建一个线程组,这个线程组默认就归属到当前线程所在的线程组中:
public class AutoGroupTest {
public static void main(String[] args) {
//首先获取一下当前线程所在的线程组
System.out.println(Thread.currentThread().getThreadGroup().getName());
ThreadGroup testGroup = new ThreadGroup("测试线程组");
System.out.println(testGroup.getParent().getName());
}
}

5,批量停止线程组里面所有的线程:interrupt

/**
* @ClassName ThreadExitAllThreadInGroup
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/26.
*/
public class ThreadExitAllThreadInGroup {
public static void main(String[] args) throws InterruptedException {
ThreadGroup threadGroup = new ThreadGroup("test线程组");
Runnable r = () -> {
String tName = Thread.currentThread().getName();
System.out.println(tName + ":线程运行中");
while (!Thread.interrupted()){}
System.out.println(tName + ":线程运行结束");
};
for (int i=0; i<10; i++){
new Thread(threadGroup,r, "T" + i).start();
}
Thread.sleep(1000);
threadGroup.interrupt();
}
}
 
 

6,多线程的异常处理:

单个线程设置异常处理:thread.setUncaughtExceptionHandler

/**
* @ClassName ThreadGroupException
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/26.
*/
public class ThreadGroupException {
public static void main(String[] args) {
Runnable r = () ->{
int a = 1/0;
};
Thread thread = new Thread(r,"test"); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
System.err.println(thread.getName() + "抛出异常:" + throwable.getMessage());
}
});
thread.start();
}
}

多个线程设置异常处理:Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler)

/**
* @ClassName ThreadGroupException
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/26.
*/
public class ThreadGroupException {
public static void main(String[] args) {
Runnable r = () ->{
int a = 1/0;
};
Thread thread = new Thread(r,"test");
Thread thread1 = new Thread(r,"test1");
Thread thread2 = new Thread(r,"test2");
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
System.err.println(thread.getName() + "抛出异常:" + throwable.getMessage());
}
});
// thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
// @Override
// public void uncaughtException(Thread thread, Throwable throwable) {
// System.err.println(thread.getName() + "抛出异常:" + throwable.getMessage());
// }
// });
thread.start();thread1.start();thread2.start();
}
}

7,线程组的异常怎么处理:

思路:之定义一个线程组,继承ThreadGroup,然后重写ThreadGroup的uncaughtExceptionHandler方法
注:
本例threadGroup  线程组实例为 Thread类的匿名子类实例化的写法
/**
* @ClassName ThreadGroupException
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/4/26.
*/
public class ThreadGroupException {
public static void main(String[] args) {
Runnable r = () -> {
int a = 1/0;
};
ThreadGroup threadGroup = new ThreadGroup("TEST-Group"){
@Override
public void uncaughtException(Thread t, Throwable e) {
System.err.println( "线程组:" + getName() + "下的线程:"+ t.getName() + "出现了异常:" + e.getMessage());
}
};
for (int i=0; i<10; i++) {
new Thread(threadGroup, r, "线程" + i).start();
}
}
}

 
 

java 多线程 线程组ThreadGroup;多线程的异常处理。interrupt批量停止组内线程;线程组异常处理的更多相关文章

  1. 线程组ThreadGroup

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

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

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

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

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

  4. 多线程 线程组 ThreadGroup

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

  5. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  6. java笔记--使用线程池优化多线程编程

    使用线程池优化多线程编程 认识线程池 在Java中,所有的对象都是需要通过new操作符来创建的,如果创建大量短生命周期的对象,将会使得整个程序的性能非常的低下.这种时候就需要用到了池的技术,比如数据库 ...

  7. Java第三阶段学习(七、线程池、多线程)

    一.线程池 1.概念: 线程池,其实就是一个容纳多个线程的容器,其中的线程可以重复使用,省去了频繁创建线程对象的过程,无需反复创建线程而消耗过多资源,是JDK1.5以后出现的. 2.使用线程池的方式- ...

  8. “全栈2019”Java多线程第三十四章:超时自动唤醒被等待的线程

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

  9. “全栈2019”Java多线程第三十一章:中断正在等待显式锁的线程

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

随机推荐

  1. docker 配置redis并远程访问

    我安装的是这个镜像 docker.io/redis docker pull docker mkdir docker cd docker mkdir redis cd redis mkdir data ...

  2. Docker之容器化学习之路v20.10.3

    Docker概述 **本人博客网站 **IT小神 www.itxiaoshen.com Docker文档官网 Docker是一个用于开发.发布和运行应用程序的开放平台.Docker使您能够将应用程序与 ...

  3. bitset 的妙用:乱搞字符串匹配

    最近碰到了几次 bitset 乱搞字符串匹配的情况,故写文以记之. 1. 算法简介 核心思想:假设文本串为 \(s\),则对字符集中的每一个字符 \(c\) 开一个大小为 \(|s|\) 的 bits ...

  4. R语言hist重叠图作法

    set.seed(1) h1<-hist(rnorm(1000,100,5)) h2<-hist(rnorm(1000,99,5)) plot(h2,col=rgb(255,0,0,50, ...

  5. perl练习——FASTA格式文件中序列GC含量计算&perl数组排序如何获得下标或者键

    一.关于程序: FUN:计算FASTA文件中每条序列中G和C的含量百分比,输出最大值及其id INPUT:FASTA格式文件 >seq1 CGCCGAGCGCTTGACCTCCAGCAAGACG ...

  6. linux sort 命令详解(转载)

    转载:http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html#3374576 sort是在Linux里非常常用的一个命令,管排序的 ...

  7. 【模板】二分图最大匹配(匈牙利算法)/洛谷P3386

    题目链接 https://www.luogu.com.cn/problem/P3386 题目大意 给定一个二分图,其左部点的个数为 \(n\),右部点的个数为 \(m\),边数为 \(e\),求其最大 ...

  8. 巩固javaweb第一天

    巩固内容: 实例解析 <!DOCTYPE html> 声明为 HTML5 文档 <html> 元素是 HTML 页面的根元素 <head> 元素包含了文档的元(me ...

  9. Android Loader异步装载

    一.Loader简介: (一).Loader的概念: 装载器从android3.0开始引进.它使得在activity或fragment中异步加载数据变得简单. 当成批显示数据的时候,为了使用户体验更好 ...

  10. oracle中注释都是问号?中文显示不出来问题

    本人在工作中需要把开发上的库恢复到自己的虚拟机里面,然而捣鼓了许久建立好数据库之后,在使用建表语句初始化表的时候,发现注释都是????? 然后一脸懵逼不知何解,网上一大堆是说修改环境变量 NLS_LA ...