JUC基礎(14):JUC概述


 

 

1 JUC

JUC 就是 java.util .concurrent 工具包的簡稱。

2 進程與線程概念

2.1 進程與線程

進程(Process) 是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。 在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。程序是指令、數據及其組織形式的描述,進程是程序的實體。
線程(thread) 是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務。
總結來說:
進程:指在系統中正在運行的一個應用程序;程序一旦運行就是進程;進程——資源分配的最小單位。
線程:系統分配處理器時間資源的基本單元,或者說進程之內獨立執行的一個單元執行流。線程——程序執行的最小單位。 

2.2 線程的狀態

線程通常都有五種狀態,創建、就緒、運行、阻塞和死亡。

  • 創建狀態。在生成線程對象,並沒有調用該對象的start方法,這是線程處於創建狀態。

  • 就緒狀態。當調用了線程對象的start方法之后,該線程就進入了就緒狀態,但是此時線程調度程序還沒有把該線程設置為當前線程,此時處於就緒狀態。在線程運行之后,從等待或者睡眠中回來之后,也會處於就緒狀態。

  • 運行狀態。線程調度程序將處於就緒狀態的線程設置為當前線程,此時線程就進入了運行狀態,開始運行run函數當中的代碼。

  • 阻塞狀態。線程正在運行的時候,被暫停,通常是為了等待某個時間的發生(比如說某項資源就緒)之后再繼續運行。sleep,suspend,wait等方法都可以導致線程阻塞。

  • 死亡狀態。如果一個線程的run方法執行結束或者調用stop方法后,該線程就會死亡。對於已經死亡的線程,無法再使用start方法令其進入就緒  

2.3 wait/sleep 的區別

(1)sleep 是 Thread 的靜態方法,wait 是 Object 的方法,任何對象實例都能調用。
(2)sleep 不會釋放鎖,它也不需要占用鎖。wait 會釋放鎖,但調用它的前提是當前線程占有鎖(即代碼要在 synchronized 中)。
(3)它們都可以被 interrupted 方法中斷。

2.4 並發與並行

2.4.1 串行模式

  串行表示所有任務都一一按先后順序進行。串行意味着必須先裝完一車柴才能運送這車柴,只有運送到了,才能卸下這車柴,並且只有完成了這整個三個步驟,才能進行下一個步驟。
   串行是一次只能取得一個任務,並執行這個任務。
2.4.2 並行模式
  並行意味着可以同時取得多個任務,並同時去執行所取得的這些任務。並行模式相當於將長長的一條隊列,划分成了多條短隊列,所以並行縮短了任務隊列的長度。並行的效率從代碼層次上強依賴於多進程/多線程代碼,從硬件角度上則依賴於多核 CPU。

2.4.3 並發

   並發(concurrent)指的是多個程序可以同時運行的現象,更細化的是多進程可以同時運行或者多指令可以同時運行。但這不是重點,在描述並發的時候也不會去扣這種字眼是否精確,==並發的重點在於它是一種現象==, ==並發描述的是多進程同時運行的現象==。但實際上,對於單核心 CPU 來說,同一時刻只能運行一個線程。所以,這里的"同時運行"表示的不是真的同一時刻有多個線程運行的現象,這是並行的概念,而是提供一種功能讓用戶看來多個程序同時運行起來了,但實際上這些程序中的進程不是一直霸占 CPU 的,而是執行一會停一會。
   要解決大並發問題,通常是將大任務分解成多個小任務, 由於操作系統對進程的調度是隨機的,所以切分成多個小任務后,可能會從任一小任務處執行。這可能會出現一些現象:
  •可能出現一個小任務執行了多次,還沒開始下個任務的情況。這時一般會采用隊列或類似的數據結構來存放各個小任務的成果
  •可能出現還沒准備好第一步就執行第二步的可能。這時,一般采用多路復用或異步的方式,比如只有准備好產生了事件通知才執行某個任務。
  •可以多進程/多線程的方式並行執行這些小任務。也可以單進程/單線程執行這些小任務,這時很可能要配合多路復用才能達到較高的效率

2.4.4 小結

並發: 同一時刻多個線程在訪問同一個資源,多個線程對一個點
例子:春運搶票 電商秒殺...
並行: 多項工作一起執行,之后再匯總
例子:泡方便面,電水壺燒水,一邊撕調料倒入桶中

3 管程

   管程(monitor)是保證了同一時刻只有一個進程在管程內活動,即管程內定義的操作在同一時刻只被一個進程調用(由編譯器實現).但是這樣並不能保證進程以設計的順序執行
 
  JVM 中同步是基於進入和退出管程(monitor)對象實現的,每個對象都會有一個管程(monitor)對象,管程(monitor)會隨着 java 對象一同創建和銷毀
 
  執行線程首先要持有管程對象,然后才能執行方法,當方法完成之后會釋放管程,方法在執行時候會持有管程,其他線程無法再獲取同一個管程

4 用戶線程和守護線程

用戶線程:平時用到的普通線程,自定義線程
守護線程:運行在后台,是一種特殊的線程,比如垃圾回收
當主線程結束后,用戶線程還在運行,JVM 存活
如果沒有用戶線程,都是守護線程,JVM 結束

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM