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. 第二章——机器学习项目完整案例(End-to-End Machine Learning Project)

    本章通过一个例子,介绍机器学习的整个流程. 2.1 使用真实数据集练手(Working with Real Data) 国外一些获取数据的网站: Popular open data repositor ...

  2. 详解Linux文档属性、拥有者、群组、权限、差异

    写在前面 我们都知道Linux是一个支持多用户.多任务的系统,这也是它最优秀的特性,即可能同时有很多人都在系统上进行工作,所以千万不要强制关机,同时,为了保护每个人的隐私和工作环境,针对某一个文档(文 ...

  3. python 文件的写删改

    # coding=utf-8 # !/usr/bin/python # -*- coding: UTF-8 -*- import io import os def file_chance(): #修改 ...

  4. django(权限、认证)系统—— 基于Authentication backends定制

    在这篇文章中,我们进行最后关于DjangoPermission系统的探讨,来谈谈关于Permission系统后台接口和扩展后台接口的开发. Django实现的这套permission体系,在底层被抽象 ...

  5. Django 基础一(安装和启动)

    在开始跟着本文学习Django进行Web开发之前你需要有一定的python编程基础,会用一些简单的Linux系统命令.如果你对python一无所知,请先去这个网站学习一下python编程的基础 Lin ...

  6. python环境下实现OrangePi Zero寄存器访问及GPIO控制

    最近入手OrangePi Zero一块,程序上需要使用板子上自带的LED灯,在网上一查,不得不说OPi的支持跟树莓派无法相比.自己摸索了一下,实现简单的GPIO控制方法,作者的Zero安装的是Armb ...

  7. shell脚本添加实例化参数

    通过shell脚本给GMP系统添加一个环境变量参数dateSwitchTimeInterval 1. insert.sh #!/bin/sh . ~/apphome/aic_export.sh #连接 ...

  8. Django_cookie_session

    登录时候后台打印request.COOKIE 1.login页面正确登录的话,后台页面可以获取到浏览器携带的cookie的. 2.第一行的sessionid其实就是cookie值 3.session的 ...

  9. ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法

    一.前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类帮我们实现对于数据库的快速访问,后来,ORM(Object Relatio ...

  10. Nginx的“远方表哥”—Tengine

    本文收录在Linux运维企业架构实战系列 今天想起当初研究nginx反向代理负载均衡时,nginx自身的upstream后端配置用着非常不舒服: 当时使用的淘宝基于nginx二次开发的Tengine, ...