zoukankan      html  css  js  c++  java
  • 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()
      }
    }
    

      

  • 相关阅读:
    LeetCode OJ String to Integer (atoi) 字符串转数字
    HDU 1005 Number Sequence(AC代码)
    HDU 1004 Let the Balloon Rise(AC代码)
    HDU 1003 Max Sum(AC代码)
    012 Integer to Roman 整数转换成罗马数字
    011 Container With Most Water 盛最多水的容器
    010 Regular Expression Matching 正则表达式匹配
    007 Reverse Integer 旋转整数
    006 ZigZag Conversion
    005 Longest Palindromic Substring 最长回文子串
  • 原文地址:https://www.cnblogs.com/barrywxx/p/9976417.html
Copyright © 2011-2022 走看看