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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM