JDK 对线程组类注释:

A thread group represents a set of threads. In addition, a thread group can also include other thread groups. The thread groups form a tree in which every thread group except the initial thread group has a parent.
A thread is allowed to access information about its own thread group, but not to access information about its thread group's parent thread group or any other thread groups.

可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示.

线程组的作用是:可以批量管理线程或线程组对象,有效地对线程或线程组对象进行组织

1.线程组示例:

展示线程组结构代码实例如下:

/**
* 类功能描述:
*
* @author WangXueXing create at 18-12-27 下午3:25
* @version 1.0.0
*/
public class ThreadGroupTest implements Runnable {
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread currentThread = Thread.currentThread();
System.out.println("current thread:" + currentThread.getName()
+" thread group:"+currentThread.getThreadGroup().getName()
+" parent thread group:"+currentThread.getThreadGroup().getParent().getName());
Thread.sleep(3000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
ThreadGroup rootThreadGroup = new ThreadGroup("root线程组1");
Thread t0 = new Thread(rootThreadGroup, new ThreadGroupTest(), "Thread 0");
t0.start();
ThreadGroup tg = new ThreadGroup(rootThreadGroup,"线程组1");
ThreadGroup tg2 = new ThreadGroup(rootThreadGroup,"线程组2");
Thread t1 = new Thread(tg, new ThreadGroupTest(), "Thread 1");
Thread t2 = new Thread(tg, new ThreadGroupTest(), "Thread 2");
t1.start();
t2.start();
Thread t3 = new Thread(tg2, new ThreadGroupTest(), "Thread 3");
Thread t4 = new Thread(tg2, new ThreadGroupTest(), "Thread 4");
t3.start();
t4.start();
}
}

  打印结果如下:

current thread:Thread 0 thread group:root线程组1 parent thread group:main
current thread:Thread 2 thread group:线程组1 parent thread group:root线程组1
current thread:Thread 1 thread group:线程组1 parent thread group:root线程组1
current thread:Thread 3 thread group:线程组2 parent thread group:root线程组1
current thread:Thread 4 thread group:线程组2 parent thread group:root线程组1
current thread:Thread 1 thread group:线程组1 parent thread group:root线程组1
current thread:Thread 0 thread group:root线程组1 parent thread group:main
current thread:Thread 2 thread group:线程组1 parent thread group:root线程组1
current thread:Thread 3 thread group:线程组2 parent thread group:root线程组1
......

  

2.线程组项目中应用(线程组内的线程异常统一管理):

最近有个需求,生成复杂报表-从很多表数据中分析统计到一个报表。

实现思路:

多个线程分别到不同表中查数据并统计分析,任何一个线程失败整体报表生成失败,记录日志并立即中断其他线程。全部线程成功,报表生成成功。

废话少说以下利用Java线程组结合CountDownLatch实现代码如下:

/**
* 多线程获取报表数据
* @param reportId 报表ID
* @return
*/
def getReportData(reportId: Long, supplierDetailMap: ConcurrentHashMap[Integer, Supplier]):
ConcurrentHashMap[Integer, AnyRef] = {
val dataMap = new ConcurrentHashMap[Integer, AnyRef]()
//多线程同步器
val conutDownLatch = new CountDownLatch(3)
//实例化线程组
val genThreadGroup = new GenThreadGroup(request.reportInfo.reportType.name, reportId)
//获取当月已开返利
new Thread(genThreadGroup, new Runnable {
override def run(): Unit = {
dataMap.put(OPENED_REBATE_CODE, SupplierAccountDetailQuerySql.getTaxDiscountByMonth(request))
conutDownLatch.countDown()
}
}, "获取当月已开返利").start() //获取当月累计解押款
new Thread(genThreadGroup, new Runnable {
override def run(): Unit = {
dataMap.put(DEPOSIT_BY_MONTH, SupplierAccountDetailQuerySql.getDepositAmountByMonth(request))
conutDownLatch.countDown()
}
}, "获取当月累计解押款").start() //结算单的含税金额
new Thread(genThreadGroup, new Runnable {
override def run(): Unit = {
dataMap.put(ACCOUNT_PAYABLE_AMOUNT, SupplierAccountDetailQuerySql.getAccountPayableAmount(request))
conutDownLatch.countDown()
}
}, "获取结算单的含税金额").start()
//所有线程都执行完成
conutDownLatch.await()
dataMap
}

  

统一捕获异常的线程组定义如下:
/**
* 定义报表生成线程组
*
* @author BarryWang create at 2018/5/21 11:04
* @version 0.0.1
*/
class GenThreadGroup(groupName: String, reportId: Long) extends ThreadGroup(groupName){
val logger: Logger = LoggerFactory.getLogger(classOf[GenThreadGroup])
/**
* 定义线程组中任意一个线程异常处理
* @param thread 当前线程
* @param exception 异常
*/
override def uncaughtException(thread: Thread, exception: Throwable): Unit = {
logger.error(s"报表(ID:${reportId})生成异常, 线程组:${groupName}; 线程:${thread.getName} 失败", exception)
thread.getThreadGroup.interrupt()
}
}

  

Java线程组(ThreadGroup)使用的更多相关文章

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

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

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

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

  3. 线程组ThreadGroup

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

  4. java线程组

    1 简介 一个线程集合.是为了更方便地管理线程.父子结构的,一个线程组可以集成其他线程组,同时也可以拥有其他子线程组. 从结构上看,线程组是一个树形结构,每个线程都隶属于一个线程组,线程组又有父线程组 ...

  5. 浅析Java中线程组(ThreadGroup类)

    Java中使用ThreadGroup类来代表线程组,表示一组线程的集合,可以对一批线程和线程组进行管理.可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的 ...

  6. java 多线程 线程组ThreadGroup;多线程的异常处理。interrupt批量停止组内线程;线程组异常处理

    1,线程组定义: 线程组存在的意义,首要原因是安全.java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的.但如果在不同的线程组中,那么就不能"跨线程组&q ...

  7. JDK中线程组ThreadGroup

    如果线程有100条...分散的不好管理... 线程同样可以分组ThreadGroup类. 线程组表示一个线程的集合.此外,线程组也可以包含其他线程组.线程组构成一棵树,在树中,除了初始线程组外,每个线 ...

  8. 多线程 线程组 ThreadGroup

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

  9. 0039 Java学习笔记-多线程-线程控制、线程组

    join线程 假如A线程要B线程去完成一项任务,在B线程完成返回之前,不进行下一步执行,那么就可以调用B线程的join()方法 join()方法的重载: join():等待不限时间 join(long ...

随机推荐

  1. websocket(一)--握手

    最近在琢磨怎么实现服务端的消息推送,因为以前都是通过客户端请求来获取信息的,如果需要实时信息就得轮询,比如通过ajax不停的请求. websocket相当于对HTTP协议进行了升级,客户端和服务端通过 ...

  2. hibernate关系映射

    多对一:比如多个订单对应同一个用户,需要在订单表中添加一个用户的属性 订单类: private Integer orderId; private Date createTime; private Us ...

  3. Java 读书笔记 (九) 运算符

    短路逻辑运算符 && 当使用与逻辑运算符时,在两个操作数都为true时,结果才为true,但是当得到第一个操作为false时,其结果就必定是false,这时候就不会再判断第二个操作了. ...

  4. Java开源生鲜电商平台-异常模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-异常模块的设计与架构(源码可下载) 说明:任何一个软件系统都会出现各式各样的异常与错误,我们需要根据异常的情况进行捕获与分析,改善自己的代码,让其更加的稳定的,快速的运行,那 ...

  5. java 中 一个int类型的num,num&1

    n&1 把n与1按位与,因为1除了最低位,其他位都为0,所以按位与结果取决于n最后一位,如果n最后一位是1,则结果为1.反之结果为0.(n&1)==1: 判断n最后一位是不是1(可能用 ...

  6. substr函数的用法

    敲了几个demo,结果如下 substr(字符串,截取开始位置,截取长度) //返回截取的字 substr('1234567890',0,5) :返回结果为 '12345' *从字符串第一个字符开始截 ...

  7. BZOJ_1877_[SDOI2009]晨跑_费用流

    BZOJ_1877_[SDOI2009]晨跑_费用流 题意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出 ...

  8. BZOJ_1934_[Shoi2007]Vote 善意的投票

    BZOJ_1934_[Shoi2007]Vote 善意的投票 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然 ...

  9. Oracle系列-锁表与解锁解决方案(大招版)-解决问题才是王道

    [Oracle系列-锁表与解锁解决方案(大招版)] --1查看被锁的表 select b.owner,b.object_name,a.session_id,a.locked_mode from v$l ...

  10. Description Resource Path Location Type Cannot change version of project facet Dynamic Web Module to 2.3.

    报错信息:Description Resource Path Location Type Cannot change version of project facet Dynamic Web Modu ...