Java线程组(ThreadGroup)使用

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()
  }
}

  

posted @ 2018-11-17 23:48  BarryW  阅读(5626)  评论(2编辑  收藏  举报