【Java】Java 線程

參考

深入理解 Java 虛擬機(第2版) 周志明

線程的實現

線程是比進程更輕量級的調度執行單位,線程的引入,可以把一個進程的資源分配與執行調度分開,各個線程既可以共享內存資源(內存地址、文件 I/O 等),又可以獨立調度(線程是 CPU 調度的基本單位)。
實現線程主要有三種方式:使用內核線程實現、使用用戶線程實現、使用用戶線程加輕量級進程混合實現。

Java 線程調度

線程調度是指系統爲線程分配處理器使用權的過程,主要調度方式有兩種:協同式線程調度(Cooperative Thread-Scheduling)、搶佔式線程調度(Preemptive Thread-Scheduling)。

協同式線程調度——線程的執行時間由線程本身來控制,線程把自己的工作執行完成了之後,要主動地通知系統切換到另外一個線程上。
協同式調度的最大好處是實現簡單,而且由於線程要把自己的事情幹完後纔會進行線程切換,切換操作是對線程自己是可知的,所以沒有什麼線程同步的問題;它的壞處是:線程執行時間不可控制,甚至如果一個線程編寫又問題,一直不告知系統進行線程切換,那麼程序就會一直阻塞在那裏(協同式不穩定,一個線程堅持不讓出 CPU 執行時間就可能會導致整個系統崩潰)。
搶佔式線程調度——每個線程由系統分配執行時間,線程的切換不由線程本身來決定(在 Java 中,Thread.yield() 可以讓出執行時間,但要獲取執行時間的話,線程本身是沒有辦法的)。
在這種實現線程調度的方式下,線程的執行時間是系統可控的,也不會有一個線程導致整個進程阻塞的問題。Java 使用的線程調度方式是搶佔式調度。

線程狀態轉換

注意:下面的線程狀態分類是 Java 中定義的線程狀態分類,和 操作系統線程狀態分類 不完全一樣。

Java 定義了 6 種線程狀態——新建(New)、運行(Runable)、無限期等待(Waiting)、限期等待(Timed Waiting)、阻塞(Blocked)、結束(Terminated),在任意一個時間點,一個線程只能有其中一種狀態。
Java 線程狀態
這些狀態是虛擬機層面上暴露給我們的狀態,這些狀態是由枚舉類Thread.State中明確定義的。看看Java
其間的轉換關係如下:
在這裏插入圖片描述
以下方法會讓線程陷入無限期的等待狀態:

  • 沒有設置 Timeout 參數的 Object.wait() 方法;
  • 沒有設置 Timeout 參數的 Thread.join() 方法;
  • LockSupport.park() 方法。

以下方法會讓線程進入有限期的等待狀態:

  • Thread.sleep() 方法;
  • 設置了 Timeout 參數的 Object.wait() 方法;
  • 設置了 Timeout 參數的 Thread.join() 方法;
  • LockSupport.parkNanos() 方法;
  • LockSupport.patkUntil() 方法。

阻塞狀態 和 等待狀態的區別
阻塞狀態在等待着獲取到一個排他鎖,這個事件將在另外一個線程放棄這個鎖時發生;而等待狀態時在等待一段時間,或者喚醒動作的發生。

By The Way:wait() 和 sleep() 的區別

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章