天天看點

線程組ThreadGroup分析詳解 多線程中篇(三)

線程組,顧名思義,就是線程的組,邏輯類似項目組,用于管理項目成員,線程組就是用來管理線程。

每個線程都會有一個線程組,如果沒有設定将會有些預設的初始化設定

而在java中線程組則是使用類ThreadGroup 進行抽象描述

既然線程組是用來管理線程的,自然更多的是一種管理次元的抽象,是以很多方法也都是這個理念

構造方法

想要了解一個類的具體資訊,第一個要看的就是構造方法,看一下最多的内容的那個構造方法就可以大緻了解到有哪些屬性了

ThreadGroup有兩個構造方法

線程組ThreadGroup分析詳解 多線程中篇(三)

仔細看下這兩個構造方法,其實隻有一個了,那就是底層的私有的這一個

線程組ThreadGroup分析詳解 多線程中篇(三)

對于一個線程組來說,他擁有他自己的名字,也擁有他的優先級,也有是否是守護的說法

不同于線程,對于線程組來說,他是有記錄自己的父線程組的,通過parent

另外,線程組也記錄了自己下面有哪些線程組,使用數組記錄,也就是構造方法中的  parent.add(this)

線程組ThreadGroup分析詳解 多線程中篇(三)

是以一個線程組核心的資訊是:名稱、優先級、是否守護、父線程組、子線程組

線程組ThreadGroup分析詳解 多線程中篇(三)

另外還有一個預設的構造方法,看注釋,用來建立系統線程組

線程組ThreadGroup分析詳解 多線程中篇(三)

名稱

線程組的名稱借助于内部的name屬性持有

通過構造方法可以設定名稱

提供了get方法用于擷取名稱

線程組ThreadGroup分析詳解 多線程中篇(三)

優先級

此處的優先級,表示的是最大允許優先級,線程組内最大就允許這麼大

裡面所有的線程不能繼續變大,不要認為是記錄了裡面所有的線程中最大的那個值,是一個天花闆,不是一個記錄尺

線程組ThreadGroup分析詳解 多線程中篇(三)

daemon

線程組ThreadGroup分析詳解 多線程中篇(三)

父線程組

對于線程組來說,是明确的記錄了他的父

借助于parent這個屬性值,可以擷取一個線程組的父線程組,也可以用來确定是否是一個指定線程組的父或者祖先

線程組ThreadGroup分析詳解 多線程中篇(三)

子線程組

内部借助于ThreadGroup 數組維護内部的線程組,從這個資料組織結構來看,就很顯然,線程組内可以有線程組,可以層層嵌套形成樹狀結構的

對于線程組的建立,他必然會有一個父線程組(不設定就是目前線程所在的線程組了,也可以簡單說目前線程組)

建立線程組的時候,就會借助于add方法,将這個線程組加入到父線程組維護的數組内

線程組ThreadGroup分析詳解 多線程中篇(三)

對于任何一個線程,也都是擁有一個線程組,如果沒有設定,将會将目前線程的線程組作為線程組,這個在前面已經說過

而在start方法中,又将目前線程添加到了線程組,請看下面的源碼截圖

線程組ThreadGroup分析詳解 多線程中篇(三)

在回頭看下這個add方法,借助于内部的線程數組,其實就是将這個線程添加到數組内

  • nThreads 記錄的就是線程組内部的線程個數
  • nUnstartedThreads記錄的是未啟動的個數

剛剛調用線程的start方法,這個數就要減1,盡管可能這個瞬間線程可能并沒有真正的啟動,確定能夠明确的聲明線程組内有啟動的線程了

線程組ThreadGroup分析詳解 多線程中篇(三)

是以就由這幾項資料組成了線程組的樹形結構

也就是說

  • 每個線程組也都知道自己包含多少個線程,哪些線程;
  • 每個線程組也都知道自己包含了多少個線程組,哪些線程組;

這是一份很重要的資訊,借助于這些資訊就完全串聯起來了

線程組ThreadGroup分析詳解 多線程中篇(三)

子線程組相關方法

既然是樹形結構,那麼自然可能有枚舉節點的需求

ThreadGroup中提供了兩類enumerate方法,看名字應該就可以了解含義了,用于枚舉線程和線程組

線程組ThreadGroup分析詳解 多線程中篇(三)

線程枚舉

底層依賴于私有枚舉方法,把此線程組及其子組中的所有活動線程複制到指定數組中。可以設定是否遞歸枚舉

兩個方法中,如果不指定是否遞歸,那麼預設是遞歸的,他們都将參數數組的第一個元素開始寫入(0号下标)

線程組ThreadGroup分析詳解 多線程中篇(三)

很顯然,他們内部就是借助于樹結構的變量,nThreads和thread[]數組

需要注意的是,如果數組内空間不足,多餘的線程将不能夠儲存進去,而且儲存的是alive狀态的

線程組ThreadGroup分析詳解 多線程中篇(三)
線程組ThreadGroup分析詳解 多線程中篇(三)

activeCount

該線程組以及子線程組中,活動線程的估計數。注意是一個估計數,估計數,估計數

線程組ThreadGroup分析詳解 多線程中篇(三)

activeGroupCount

類似activeCount,這個方法是傳回的線程組的個數,仍舊是估計數,估計數,估計數

線程組ThreadGroup分析詳解 多線程中篇(三)

list方法

list看注釋,用于調試,底層依賴方法list(PrintStream out, int indent),indent表示的是縮進,也就是空格個數

仍舊是借助于nthreads和ngroups以及threads數組和group數組,也就是樹形結構循環周遊列印資訊

線程組ThreadGroup分析詳解 多線程中篇(三)

interrupt()方法

中斷此線程組中的所有線程,可以看得出來:

仍舊是周遊樹形結構,核心是調用所有線程的interrupt方法

是以,此方法是中斷該線程組以及所有子線程組中的所有線程

線程組ThreadGroup分析詳解 多線程中篇(三)

線程組的銷毀

線程組的銷毀内部借助于boolean變量 destroyed 進行辨別

getter方法,isDestroyed直接傳回此字段

而setter方法destroy,也是設定這個字段,但是還有一些邏輯判斷與處理

destroy()負責銷毀此線程組及其所有子組。

  • 會進行權限校驗
  • 并且此線程組必須為空,也就是nthreads > 0不成立,也就是此線程組中的所有線程都已停止執行。
  • 并且會将子線程組中的也進行銷毀,是遞歸進行的,顯然,如果子線程組中線程非空,那麼仍舊會抛出異常
線程組ThreadGroup分析詳解 多線程中篇(三)

權限校驗checkAccess

checkAccess就是總提到的一個借助于安全管理器進行權限校驗的封裝

确定目前運作的線程是否有權修改此線程組

線程組ThreadGroup分析詳解 多線程中篇(三)

異常處理器

uncaughtException,是用于異常處理的設定,此處不講,後續單獨章節。

總結

從前面的描述可以看得出來,線程組就是對線程進行管理的一個抽象建構,他包括了自身的一些資訊,還有一大部分就是對于線程的管理

線程組中有線程,也有線程組,借助于兩個變量和兩個數組完成了樹形結構的構造,很多方法都是借助于這個樹形結構完成的,比如枚舉

想要了解線程組,就要了解線程組“管理”角色的内涵,并且對線程組的樹形結構了解

既然是管理線程,是以線程中的一些功能或者屬性也是依賴線程組的,比如優先級,線程不能超過線程組的最大優先級,再比如Thread中的activeCount(),實際上就是currentThread().getThreadGroup().activeCount();

總之,一定要了解管理二字的含義

原文位址:線程組ThreadGroup分析詳解 多線程中篇(三)