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. Spring Cloud Gateway过滤器精确控制异常返回(实战,控制http返回码和message字段)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<Spring Cloud Gat ...

  2. SpringSecurity 小demo

    SpringSecurity 首先搭建好springboot工程,然后引入springsecurity依赖. <dependency> <groupId>org.springf ...

  3. CF814E An unavoidable detour for home

    考虑有每个最短路只有一条. 那么我们建出最短路树后,显然所有的非树边都是同层之间的横叉边. 那么我们考虑设\(f(i,j,k,z)\)为我们考虑到了第\(i\)个点,此时他被我们分配到了\(p\)层, ...

  4. windows系统开/关机日志位置

    邮件计算机=>管理 =>系统工具=>事件查看器=>Windows日志=>系统 过滤:关机:事件ID=6006 开机:事件ID=6005

  5. C语言计算fastq文件GC含量

    C语言小练习:计算非压缩fastq格式的GC含量 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <strin ...

  6. yum和apt-get的用法和区别

    一般来说著名的linux系统基本上分两大类: 1.RedHat系列:Redhat.Centos.Fedora等 2.Debian系列:Debian.Ubuntu等 RedHat 系列 1 常见的安装包 ...

  7. vim 的使用

    基本操作:  命令行模式 进入命令行 打开文本的时候,直接进去命令行模式 在其它模式按ESC,可以进入命令行模式 新建进入了命令行模式 光标进入末行"G"(shift+按键g,自学 ...

  8. 日常Java 2021/10/5

    java 异常处理 Throwable中包括Error 和Exception,Exception包括IOException和RuntimeException 抛出异常 1.异常运算条件 Arithme ...

  9. accommodate, accompany

    accommodate 词源: to make fit, suitable; 近/反义词: adapt, adjust, lodge; disoblige, incommode, misfit Lod ...

  10. @Transactional注解详细使用

    一.@Transactional 注解使用 @Transactional  注解只能用在public 方法上,如果用在protected或者private的方法上,不会报错,但是该注解不会生效. @T ...