【多執行緒與高並發】從一則招聘資訊進入多執行緒的世界

多執行緒的學習方法

多執行緒作為面試的重災區,如果我們能夠進行深入的了解和使用,對我們而言是非常有有益的,尤其是在面試的時候,如果多執行緒回答的好,是非常能夠加分的。這樣才能夠經受住面試官的奪命連環問!

不管學什麼,我們都需要有一個整體的認知,俯瞰其全貌,了解其細節,如果可以的話,最好是畫一個思維導圖,將其中的分支和一個個的小的知識點,記錄上去,方便我們學習的時候,逐步有條理的分解性學習,從而達到從點到面,從面到體的過程。

多於多執行緒的學習,比較推薦的自然還是自己動手做小實驗和了解理論基礎,我們在時間充裕的情況下,可以看有關於多執行緒的書籍,比如(Java多執行緒編程核心技術、Java並發編程實戰 (java並發的聖經)、多處理器編程的藝術)等等,但是對於時間不太充裕的同學,看書和自己動手實踐的時間就會比較少,這個時候我們只能靠背、看面試題的方法去學習。

壓榨CPU性能

在之前的時候,小農有看到一個面試要求,小農看到了覺得很有意思,就記錄下來了,是什麼呢?

  1. Java基礎紮實,熟悉JVM、多執行緒、集合等基礎,熟悉分散式、快取、消息、搜索等機制
  2. 三年以上Java開發經驗,熟悉Spring、MyBatis等框架
  3. 對於壓榨CPU性能有濃厚興趣!
  4. 具有一定項目規劃和決策能力,善於捕捉業務需求、系統架構設計中存在的問題,並給出有效的解決方案
  5. 具有高度領域設計能力和業務分析能力,能獨立分析和解決問題

我們看到第三條,對CPU性能壓榨有濃厚的興趣,執行緒的歷史,就是對電腦CPU壓榨的一個歷史,當我們的多執行緒越多效率越高,對於CPU的壓榨也就越厲害,但是壓榨的時候我們也需要注意,在壓榨的同時,保證程式的正常運行也是我們需要考慮的一個點。

執行緒的歷史

對於執行緒的歷史,其實就是對於伺服器的CPU進行不斷的利用的升級過程。當我們學習一個新技術的時候,去了解這個技術的背景,可以更好的了解和掌握新技術,雖然這個過程看起來無用且浪費時間,但是在我們後面的學習過程,能夠幫助我們更好的理解新技術。從執行緒的發展來看,可以分為五個階段:

1、單進程

最早的就是單進程進行人工切換,那個時候的程式,一次就只能運行一個程式,當我們想要切換別的程式的時候,只能人工停止當前程式,再來運行別的程式,這個時候CPU利用率不高,很多時候是等著人工來進行干預,如下圖所示:

在這裡插入圖片描述

2、批處理

慢慢的有人就覺得這種方式太慢了,或者太影響效率了,於是就有了多進程批處理,可以理解為,在我們進程裡面,有ABCDF五個程式,我們可以一次性輸出這五個程式,不用再他們之間在進行切換,但是如果程式A阻塞了,那麼其他四個程式就需要進行等待,如下圖所示:

在這裡插入圖片描述

3、並行處理

把程式寫在不同的記憶體位置上來回切換,比如我們有ABC三個程式,程式A去CPU進行運算,但是由於網路的延遲或者什麼原因,導致程式A阻塞了,那麼這個時候程式B就可以去CPU裡面去執行,如果程式B也阻塞了,那麼程式C就可以去CPU裡面執行

在這裡插入圖片描述

4、多執行緒

程式內部可以有不同的任務進行來回的執行緒切換,比如說我們使用的IDEA,它內部可能有的在等待網路的傳輸,有的在進行程式碼的展示,有的在進行save,將我們的程式碼保存在歷史記錄等等,這些個任務他們執行的時候也是並行的執行的,這個時候就產生了執行緒的概念,執行緒是屬於一個進程裡面並行執行的這樣的不同的路線,一個程式不同任務的切換,一個執行緒如果要提升他的效率的,內部其實是非常複雜的。其中設計到網路和IO的知識。

5、纖程/協程

是一種最輕量化的執行緒,一種綠色的執行緒,它也是一種用戶執行緒,就是有用戶自己管理,不再由電腦去管理,
讓應用程式可以獨立決定自己的執行緒要如何運作。作業系統內核不能看見它,也不會為它進行調度,纖程有自己的定址空間。應用程式可以在一個執行緒環境中創建多個纖程,然後手動運行它。纖程不會被自動運行,必須要由應用程式自已指定讓它運行,或換到下一個纖程。

進程/執行緒/纖程

1、什麼是進程

進程就是說在系統中正在運行的應用程式,程式一旦運行就是進程,比如我們常用的QQ,WeChat等等,進程是系統進行資源分配的獨立實體,每個進程都有自己獨立的地址空間,一個進程可以有多個執行緒,每個執行緒使用自己所屬進程的棧空間。

// 進程:是作業系統資源分配的基本單位,比如記憶體、打開文件、網路IO,分配了獨立的記憶體空間
public class T00_Process {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

在這裡插入圖片描述

在這裡插入圖片描述

2、什麼是執行緒

執行緒是程式執行的最小單位,它被包含在進程之中,是進程中的實際運作單位。一條執行緒指的是一個單一順序的控制流,一個進程中可以並發多個執行緒,每條執行緒並行執行不同的任務,通常也被稱為輕量進程。

單執行緒:

單執行緒下,不同的執行路徑
在這裡插入圖片描述

多執行緒:
在這裡插入圖片描述

3、什麼是纖程

纖程(Fiber)包含獨立的目態棧,暫存器狀態的控制資訊,目態控制的纖程轉接要求較高的編程經驗,由於纖程屬於目態對象,一個纖程被封鎖意味著所在執行緒被封鎖,應用程式可以通過ConvertThreadToFiber將執行緒轉換為纖程,與執行緒對比,纖程具有切換速度快的特點。

纖程具有的特徵

  • 執行緒是在Windows內核中實現的,作業系統會根據系統的調度演算法對執行緒進行調度。
  • 纖程是在用戶模式下實現的,內核對纖程一無所知。
  • 纖程是更輕量級的執行緒,一個執行緒可以包含一個或多個纖程

什麼是執行緒的切換

什麼是執行緒的上下文切換?:
多執行緒的上下文切換是指 CPU 控制權由一個已經正在運行的執行緒切換到另外一個就緒並等待獲取 CPU 執行權的執行緒的過程。

單核CPU設定多執行緒是否有意義

通常一個任務不光 cpu 上要花時間, io 上也要花時間(例如去資料庫查數據,去抓網頁,讀寫文件等)。 一個進程在等 io 的時候, cpu 是閑置的,另一個進程正好可以利用 cpu 進行計算。 多幾個進程一起跑,可以把 io 和 cpu 都跑滿了。
現在一般都是虛擬資源,資源有彈縮機制,所以一般該跑多執行緒的時候就可以跑多執行緒。

工作執行緒數是不是設置的越大越好

當然不是,執行緒的切換也是需要消耗資源的,越多意味著執行緒來回之間的切換。

我是牧小農,怕什麼真理無窮進一步有進一步的歡喜,大家加油