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

線程組,顧名思義,就是線程的組,邏輯相似項目組,用於管理項目成員,線程組就是用來管理線程。
每一個線程都會有一個線程組,若是沒有設置將會有些默認的初始化設置
而在java中線程組則是使用類ThreadGroup 進行抽象描述
既然線程組是用來管理線程的,天然更多的是一種管理維度的抽象,因此不少方法也都是這個理念

構造方法

想要了解一個類的具體信息,第一個要看的就是構造方法,看一下最多的內容的那個構造方法就能夠大體瞭解到有哪些屬性了
ThreadGroup有兩個構造方法
image_5c5bc1e2_25a7
仔細看下這兩個構造方法,其實只有一個了,那就是底層的私有的這一個
image_5c5bc1e2_7e2a
對於一個線程組來講,他擁有他本身的名字,也擁有他的優先級,也有是不是守護的說法
不一樣於線程,對於線程組來講,他是有記錄本身的父線程組的,經過parent
另外,線程組也記錄了本身下面有哪些線程組,使用數組記錄,也就是構造方法中的  parent.add(this)
image_5c5bc1e2_41dc
因此一個線程組核心的信息是:名稱、優先級、是否守護、父線程組、子線程組
image_5c5bc1e2_e8a
另外還有一個默認的構造方法,看註釋,用來建立系統線程組
image_5c5bc1e2_71aa  

名稱

線程組的名稱藉助於內部的name屬性持有
經過構造方法能夠設置名稱
提供了get方法用於獲取名稱
image_5c5bc1e3_311e

優先級

此處的優先級,表示的是最大容許優先級,線程組內最大就容許這麼大
裏面全部的線程不能繼續變大,不要認爲是記錄了裏面全部的線程中最大的那個值是一個天花板,不是一個記錄尺
image_5c5bc1e3_41bb

daemon

image_5c5bc1e3_6ba7

父線程組

對於線程組來講,是明確的記錄了他的父
藉助於parent這個屬性值,能夠獲取一個線程組的父線程組,也能夠用來肯定是不是一個指定線程組的父或者祖先
image_5c5bc1e3_4090

子線程組

內部藉助於ThreadGroup 數組維護內部的線程組,從這個數據組織結構來看,就很顯然,線程組內能夠有線程組,能夠層層嵌套造成樹狀結構的
對於線程組的建立,他必然會有一個父線程組(不設置就是當前線程所在的線程組了,也能夠簡單說當前線程組)
建立線程組的時候,就會藉助於add方法,將這個線程組加入到父線程組維護的數組內
image_5c5bc1e3_57fc
對於任何一個線程,也都是擁有一個線程組,若是沒有設置,將會將當前線程的線程組做爲線程組,這個在前面已經說過
而在start方法中,又將當前線程添加到了線程組,請看下面的源碼截圖
image_5c5bc1e3_64b3
在回頭看下這個add方法,藉助於內部的線程數組,其實就是將這個線程添加到數組內
  • nThreads 記錄的就是線程組內部的線程個數
  • nUnstartedThreads記錄的是未啓動的個數
剛剛調用線程的start方法,這個數就要減1,儘管可能這個瞬間線程可能並無真正的啓動,確保可以明確的聲明線程組內有啓動的線程了
image_5c5bc1e3_4549
因此就由這幾項數據組成了線程組的樹形結構
也就是說
  • 每一個線程組也都知道本身包含多少個線程,哪些線程;
  • 每一個線程組也都知道本身包含了多少個線程組,哪些線程組;
這是一份很重要的信息,藉助於這些信息就徹底串聯起來了
image_5c5bc1e3_5044

子線程組相關方法

既然是樹形結構,那麼天然可能有枚舉節點的需求
ThreadGroup中提供了兩類enumerate方法,看名字應該就能夠理解含義了,用於枚舉線程和線程組
image_5c5bc1e4_264a

線程枚舉

底層依賴於私有枚舉方法,把此線程組及其子組中的全部活動線程複製到指定數組中。能夠設置是否遞歸枚舉
兩個方法中,若是不指定是否遞歸,那麼默認是遞歸的,他們都將參數數組的第一個元素開始寫入(0號下標)
image_5c5bc1e4_7c3
很顯然,他們內部就是藉助於樹結構的變量,nThreads和thread[]數組
須要注意的是,若是數組內空間不足,多餘的線程將不可以保存進去,並且保存的是alive狀態的
image_5c5bc1e4_1f6a
 
image_5c5bc1e4_302e

activeCount

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

activeGroupCount

相似activeCount,這個方法是返回的線程組的個數,仍舊是估計數,估計數,估計數
image_5c5bc1e4_1721

list方法

list看註釋,用於調試,底層依賴方法list(PrintStream out, int indent),indent表示的是縮進,也就是空格個數
仍舊是藉助於nthreads和ngroups以及threads數組和group數組,也就是樹形結構循環遍歷打印信息
image_5c5bc1e4_2f8

interrupt()方法

中斷此線程組中的全部線程,能夠看得出來:
仍舊是遍歷樹形結構,核心是調用全部線程的interrupt方法
因此,此方法是中斷該線程組以及全部子線程組中的全部線程
image_5c5bc1e4_224c

線程組的銷燬

線程組的銷燬內部藉助於boolean變量 destroyed 進行標識
getter方法,isDestroyed直接返回此字段
而setter方法destroy,也是設置這個字段,可是還有一些邏輯判斷與處理
destroy()負責銷燬此線程組及其全部子組。
  • 會進行權限校驗
  • 而且此線程組必須爲空,也就是nthreads > 0不成立,也就是此線程組中的全部線程都已中止執行。
  • 而且會將子線程組中的也進行銷燬,是遞歸進行的,顯然,若是子線程組中線程非空,那麼仍舊會拋出異常
image_5c5bc1e4_172d

權限校驗checkAccess

checkAccess就是總提到的一個藉助於安全管理器進行權限校驗的封裝
肯定當前運行的線程是否有權修改此線程組
image_5c5bc1e4_6d5d

異常處理器

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

總結

從前面的描述能夠看得出來,線程組就是對線程進行管理的一個抽象構建,他包括了自身的一些信息,還有一大部分就是對於線程的管理
線程組中有線程,也有線程組,藉助於兩個變量和兩個數組完成了樹形結構的構造,不少方法都是藉助於這個樹形結構完成的,好比枚舉
想要理解線程組,就要理解線程組「管理」角色的內涵,而且對線程組的樹形結構瞭解
既然是管理線程,因此線程中的一些功能或者屬性也是依賴線程組的,好比優先級,線程不能超過線程組的最大優先級,再好比Thread中的activeCount(),實際上就是currentThread().getThreadGroup().activeCount();
總之,必定要理解管理二字的含義
相關文章
相關標籤/搜索