Java併發基礎(一)-線程基礎

只要涉及到線程,其運行結果就是不確定的,雖然說java很早就提供了線程以及併發的支持,但是我們需要知道,線程是完全交給調度器的。有很多同學在編寫書上的代碼時,會發現運行結果不一致,其實這不是書上的例子錯了,而是運行環境不一致導致的(cpu核數).

而接下來的所涉及到到線程,指的是語言層次的線程,而不是操作系統層次的。

1. Java語言中線程的實現

從JDK 1.2 開始,JVM中的線程模型替換爲了基於操作系統原生線程模型來實現的,因此,操作系統支持怎樣的線程模型,很大程度上決定了JVM的線程模型。

在Java語言中,提供了兩種實現線程的方式,Thread類和Runnable接口。對於怎麼使用,這裏就不說了。

2. Java線程調度

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

有的朋友可能會說,Java的線程調度方式是搶佔式的。通過線程模型的實現可以知道,在JDK1.2之後,線程模型很大程度上取決與操作系統。而Java中的線程調度就是搶佔式調度。

2.1 協同式調度

線程的執行時間完全由線程本身決定,線程執行完畢纔會通知系統進行線程切換。

  • 優點
    • 實現簡單
  • 缺點
    • 線程執行時間不可控

2.2 搶佔式調度

線程的執行時間由系統來分配,線程切換不由線程本身決定

  • 優點
    • 系統可控
2.2.1 優先級調度

雖然我們可以設置優先級,建議系統給線程分配更多的時間,但是,這是不可靠的。因爲線程調度最終還是取決於操作系統。通過Thread.yield()方法可以讓出執行時間,讓優先級更高的線程先執行。

3. 狀態轉換

  • 新建狀態(new) 創建後尚未啓動的線程
  • 運行狀態(Runnable) 注意:這裏的線程可能正在運行,也可能在等待CPU分配時間片段
  • 等待狀態
    • 無限期等待(Waiting) 這種狀態不會被分配時間片段,需要被喚醒
      • 沒設置時間(無期限)Object.wait()方法 |
      • 沒設置時間(無期限)Thread.join()方法
      • LockSupport.park()方法
    • 期限等待(Timed Waiting) 等待一段時間後,就可以被分配時間片段
      • Thread.sleep()
      • 設置了時間的Object.wait()
      • 設置了事件的Thread.join()
      • LockSupport.parkNanos()
      • LockSupport.parkUntil()
  • 阻塞(blocked) 等待獲取鎖
  • 結束狀態(Terminated) 線程執行完畢,終止線程的線程狀態。

4.如何回收線程

回收線程防止內存泄露。一般來說如下

Thread.interrupt() //產生中斷
Thread.join() //等待死亡


參考資料

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