1. 程式人生 > >Java併發程式設計三:併發(Concurrent)與並行(Parallel)的區別(一)

Java併發程式設計三:併發(Concurrent)與並行(Parallel)的區別(一)

併發(Concurrent)與並行(Parallel)是一個大家比較容易混淆的概念。大家在解釋併發與並行的時候一般這樣說:

  1. 多執行緒是併發執行的;
  2. 多核CPU是並行執行的,單核CPU是不可以不行執行的;

以上說法也是可以理解的,大家都是基於場景來描述的。為了搞清楚這個問題,我查閱了一些資料,發現這篇譯文:併發不是並行,它更好中的圖片很好的說明了併發與並行的區別。

定義

網路上找到的定義如下:

併發(Concurrent):以可獨立執行的程序集合的方式程式設計(程序是出了名的難定義,這裡是通常意義上的程序,不是Linux程序)。

並行(Parallel):以可同時執行的(可能相關的)計算指令方式程式設計。

我的理解:

併發(Concurrent):是一種構造程式的方式,把任務分解為一個個獨立執行的小任務。通訊是協調這些小任務的手段。

並行(Parallel):以分組的方式,同時執行每一組併發任務。

兩者的區別:併發是同時處理(dealing)很多的事情,並行是同時做(doing)很多的事情。

以上的講解太抽象了,我們通過例項來講解,舉例如下:

我們的問題:把一堆廢棄的說明書運到火爐裡,一隻地鼠會花費很長時間。

方案一

一隻地鼠,使用一輛推車,將書裝到車上,運輸到火爐旁,將書卸到火爐。

這裡寫圖片描述

方案二

有兩隻地鼠,一隻地鼠,使用一輛推車,將書裝到車上,運輸到火爐旁,將書卸到火爐。另一隻地鼠出於等待中,顯然增加更多的地鼠是無法解決效率問題的,也需要同時增加推車。(當然有人說兩隻地鼠輪流使用一輛推車,這樣可以讓地鼠得到休息,這樣它們幹活更快,也可以提高效率。)

這裡寫圖片描述

方案三

兩隻地鼠,兩輛推車,分別使用各自的推車,將書裝到車上,運輸到火爐旁,將書卸到火爐。這樣會提高運輸效率,但它們會在裝書和卸書時進行排隊,降低了效率。

這裡寫圖片描述

方案四

基於方案一的改進,將書堆拆分成兩部分,同時增加一個火爐。該方案有兩種可能:
1、只地鼠運一次上面那堆書,然後第二隻地鼠再運一次下面那堆書。一次只允許一隻地鼠運送,這樣就不是並行的。
2、兩隻地鼠,兩輛推車,分別使用各自的推車,把各自書堆的書裝到車上,運輸到各自的火爐旁,將書卸到火爐。這樣提高了運輸效率,而且在裝書和卸書時不會進行排隊,提高了裝卸的效率。

這裡寫圖片描述

方案五

三隻地鼠在工作,一隻負責把書裝到車上,一隻負責運輸,一隻負責把書卸到火爐。每隻地鼠做一個獨立的任務。
這裡寫圖片描述

方案六

四隻地鼠在工作,一隻負責把書裝到車上,一隻負責運輸,一隻負責把書卸到火爐,一隻負責運回空推車。每隻地鼠做一個獨立的任務。
這裡寫圖片描述

觀察結論:我們在一個已有的設計(指三個地鼠的那個設計)中新增一個併發的步驟(第四隻地鼠)增強了系統的效能。更多的地鼠幹了更多的活,系統執行得更好。併發比簡單的並行對問題要有更深的洞察。

我們有四個併發的步驟:

 1. 把書裝到車上;
 2. 把推車運到火爐旁;
 3. 把書卸到火爐裡;
 4. 運回空推車。

不同的併發設計能以不同的方式來並行。

方案七

增加一個方案六的分組,使兩個分組並行執行。

這裡寫圖片描述

方案八

兩隻地鼠,再加上一個中轉堆。這也是一種用併發來解決問題的方案。

這裡寫圖片描述

方案九

增加一個方案八的分組,使兩個分組並行執行。

這裡寫圖片描述

方案十

在多地鼠併發模型中引入中轉堆

這裡寫圖片描述

方案十一

增加一個方案十的分組,使兩個分組並行執行。

這裡寫圖片描述

總結

我們有很多方法把問題分解,這才是併發設計。一旦我們分解了問題,並行就自然而然的產生了。

回到兩者的區別這個問題上:

併發是同時處理(dealing)很多的事情,如方案六,同時處理一下四個併發步驟:

 1. 把書裝到車上;
 2. 把推車運到火爐旁;
 3. 把書卸到火爐裡;
 4. 運回空推車。

並行是同時做(doing)很多的事情,如方案十一,分為兩組同時執行任務。這就是我對併發與並行的理解。

參考資料