1. 程式人生 > 實用技巧 >Java併發程式設計基礎概念

Java併發程式設計基礎概念

這篇隨筆梳理一下Java併發程式設計的一些基礎概念。包括同步非同步、程序執行緒、併發並行。

同步和非同步是指方法的呼叫,我們用一張圖來形容:

同步方法一旦呼叫後,呼叫者必需等方法執行完畢後才能進行後續的行為;

非同步方法一旦被呼叫則會立即返回,呼叫者可以繼續後面的行為,非同步方法一般會在另外一個執行緒中執行;如果非同步方法有返回結果,通常會由系統通知呼叫者;

其次是程序、執行緒;

程序:

  • 程式由指令和資料組成,但這些指令要執行,資料要讀寫,就必須將指令載入至 CPU,資料載入至記憶體。在指令執行過程中還需要用到磁碟、網路等裝置。程序就是用來載入指令、管理記憶體、管理 IO 的。
  • 當一個程式被執行,從磁碟載入這個程式的程式碼至記憶體,這時就開啟了一個程序。
  • 程序就可以視為程式的一個例項。大部分程式可以同時執行多個例項程序(例如記事本、畫圖、瀏覽器等),也有的程式只能啟動一個例項程序(例如網易雲音樂、360 安全衛士等)

執行緒

  • 一個程序之內可以分為一到多個執行緒。
  • 一個執行緒就是一個指令流,將指令流中的一條條指令以一定的順序交給 CPU 執行。

比較

  • Java 中,執行緒cpu最小排程單位,程序是資源分配的最小單位。 在 windows 中程序是不活動的,只是作為執行緒的容器.
  • 程序基本上相互獨立的,而執行緒存在於程序內,是程序的一個子集
  • 程序擁有共享的資源,如記憶體空間等,供其內部的執行緒共享
  • 程序間通訊較為複雜
    • 同一臺計算機的程序通訊稱為 IPC(Inter-process communication)
    • 不同計算機之間的程序通訊,需要通過網路,並遵守共同的協議,例如 HTTP
  • 執行緒通訊相對簡單,因為它們共享程序內的記憶體,比如多個執行緒可以訪問同一個共享變數
  • 執行緒更輕量,執行緒上下文切換成本一般上要比程序上下文切換低

最後就是併發和並行了。

併發

 單核 cpu 下,執行緒實際還是序列執行的。作業系統中有一個元件叫做任務排程器,會將 cpu 的時間片(windows下時間片最小約為 15 毫秒)分給不同的程式使用,由於 cpu 線上程間(時間片很短)的切換非常快,我們感覺是同時執行的 。總結為一句話就是: 微觀序列,巨集觀並行。用圖例表示如下,cpu輪流執行這些執行緒。

一般會將這種執行緒輪流使用 CPU

的做法稱為併發(concurrent)。

CPU 時間片1時間片2時間片3時間片4
core 執行緒 1 執行緒 2 執行緒 3 執行緒 4

並行

多核 cpu下,每個 核(core) 都可以排程執行執行緒,這時候執行緒可以是並行的。

CPU 時間片1時間片2時間片3時間片4
core1 執行緒 1 執行緒 1 執行緒 3 執行緒 3
core2 執行緒 2 執行緒 4 執行緒 2 執行緒 4

同樣可以用圖來描述:

總結一下就是(Rob Pike):

  • 併發(concurrent)是同一時間應對(dealing with)多件事情的能力
  • 並行(parallel)是同一時間動手做(doing)多件事情的能力

大多時候並行和併發是同時進行的,舉一個生活中的例子來說明:

  • 家裡面保姆做飯、打掃衛生、給孩子餵奶,她一個人輪流交替做這多件事,這時就是併發
  • 主人又僱了個保姆,她們一起這些事,這時既有併發,也有並行(這時會產生競爭,例如鍋只有一口,一個人用鍋時,另一個人就得等待)
  • 又僱了個保姆,三個人一個專做飯、一個專打掃衛生、一個專餵奶,互不干擾,這時是並行。