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

      

  • 相关阅读:
    apache设置无缓存
    唤醒键盘时取消对特定类的position:fixed定位
    vscode增加sftp扩展
    浮层蒙版加载中实现方式
    管理应用程序版本Elastic Beanstalk
    向 Elastic Beanstalk 环境中添加数据库
    在 Amazon ECS 上运行 X-Ray 守护程序
    SNS Message Attributes
    ProvisionedThroughputExceededException
    使用 Amazon CloudWatch Events 检测和响应管道状态更改
  • 原文地址:https://www.cnblogs.com/barrywxx/p/9976417.html
Copyright © 2011-2022 走看看