天天看點

Java進階工程師蛻變·多線程·深入了解Thread構造函數

一、線程的命名

        在構造線程的時候可以為線程起一個有特殊意義的名字,這也是一種比較好的做法,有助于排查問題。

沒有提供線程命名參數的構造函數:

  • Thread()
  • Thread(Runnable target)
  • Thread(ThreadGroup group,Runnable target)

如果沒有為線程顯式的指定一個名字,那麼線程将會以"Thread-"作為字首于自增數字進行組合,這個數字在JVM中不斷自增。

提供了指定線程名稱的構造函數:

  • Thread(Runnable target,String name)
  • Thread(String name)
  • Thread(ThreadGroup group,Runnable target,String name)
  • Thread(ThreadGroup group,Runnable target,String name,long stackSize)
  • Thread(ThreadGroup group,String name)

二、Thread與ThreadGroup

1.main線程所在的ThreadGroup稱為main

2.構造一個線程的時候如果沒有顯式的指定ThreadGroup,那麼他将會和父線程同屬于一個ThreadGroup

三、JVM記憶體結構

1.程式計數器

        程式計數器在JVM中所起的作用就是用于存放目前線程接下來将要執行的位元組碼指令、分支、循環、跳轉、異常處理等資訊。每條線程都具有一個獨立的程式計數器,各個線程之間互不影響,程式計數器是線程私有的。

2.Java虛拟機棧

        Java虛拟機棧也是線程私有的,它的生命周期和線程相同,是在JVM運作時所建立的。線上程中,方法在執行的時候都會建立一個名為棧幀的資料結構,主要用于存放局部變量表、操作棧、動态連結、方法出口等資訊。虛拟機棧的大小可以通過-xss來配置,同等的虛拟機棧如果局部變量表等記憶體越小則可被壓入的棧幀就會越多。

3.本地方法棧

        Java中提供了調用本地方法的接口,也就是C/C++程式,JVM為本地方法所劃分的記憶體區域便是本地方法棧,也是線程私有的記憶體區域。

4.堆記憶體

        堆記憶體是JVM中最大的一塊記憶體區域,被所有的線程所共享,Java在運作期間建立的所有對象幾乎都在該記憶體區域,該區域也是垃圾回收器重點照顧的區域,又稱“GC堆”。

5.方法區

        方法區也是被多個線程共享的記憶體區域,它主要用于存儲已經被虛拟機加載的類資訊、常量、靜态變量、即時編譯器(JIT)編譯後的代碼等資料。

6.Java 8 元空間

        JDK1.8版本起,JVM的記憶體區域發生了一些改變,持久代記憶體被徹底删除,取而代之的是元空間。元空間是堆記憶體的一部分,JVM可以減少記憶體碎片,節省GC掃描和壓縮的時間。

四、Thread與虛拟機棧

        虛拟機棧記憶體與線程的建立、運作、銷毀等關系密切,虛拟機棧記憶體是線程私有的,堆記憶體固定,棧記憶體越大,JVM可建立的線程數量越小。堆記憶體的增大對線程數量的影響也是反比關系,但是并沒有像棧記憶體那樣明顯。

線程數量=(最大位址空間-JVM堆記憶體-ReservedOsMemory)/ThreadStackSize(XSS)

注1:作業系統中一個程序的記憶體大小是有限制的,這個限制稱為位址空間。

注2:ReservedOsMemory是系統保留記憶體,一般在136MB左右。

五、守護線程

        守護線程是一類比較特殊的線程,一般用于處理一些背景的工作,比如JDK的垃圾回收線程。守護線程具備自動結束生命周期的特性,适合執行一些背景任務,在退出JVM程序的時候,線程可以自動關閉。

        設定守護線程的方法很簡單,調用setDaemon方法即可,true代表守護線程,false代表正常線程。線程是否為守護線程跟他的父線程有關系,父線程是正常線程,則子線程也是正常線程,反之亦然。另外,setDaemon方法隻線上程啟動之前才能生效。