1. 程式人生 > >02-理解多執行緒與併發之間的聯絡與區別

02-理解多執行緒與併發之間的聯絡與區別

多執行緒和併發之間到底有什麼關聯呢?它們之間又有哪些差異呢?我們本節課就來探討一下。

首先說一下什麼是多執行緒,其實之前已經給大家講了一個非常簡單的例子了

假如這是我們的一個應用,假如我們在這裡面寫程式碼

我們知道,程式是一行一行的往下執行的,在Java虛擬機器執行時記憶體區域中,有一塊叫做PC暫存器,類似於程式碼編輯器中的linenumber,指示的是行號,Java虛擬機器就跟著行號一行一行的往下執行。

肯定不會說從執行完int a = 10; 之後,接著先執行int c = a + b; 然後再回過頭去執行int b = 20; 這是絕對不可能的,這就是單個執行緒在執行,就是說,這裡面的程式碼是一行一行的往下去執行的,不會亂序去執行,我們知道,在執行這段程式碼的同時

當然這段程式碼不會,比如說執行一個非常複雜的程式碼的過程中,我們知道,Java的記憶體管理,我們並不需要手動的去管理記憶體,Java提供了自動記憶體管理機制,記憶體的申請和釋放都是由Java虛擬機器來自己完成的,那麼,在進行垃圾回收的過程中,就需要呼叫垃圾收集器(GC),那麼,你這個程式在執行的過程中,垃圾收集器也是在工作的,我們發現,我們並不知道垃圾收集器在工作,但是,垃圾收集器卻是已經在工作了,怎麼回事呢?其實,有另外一個執行緒在執行垃圾收集器,就是專門的垃圾收集器執行緒,它裡面也有一行一行的垃圾收集程式碼

那麼,在我們程式執行的過程中,這些程式碼會自動的悄悄的往下去執行。Java虛擬機器中的記憶體區域,我們這裡不去詳細的說,主要分為兩大區域,一個是執行緒共享區,一個是執行緒獨佔區,我們知道,堆和方法區是被執行緒所共享的區域,就是所有的執行緒共享這塊區域,除了這兩塊區域以外,還有程式計數器

這塊區域是被執行緒所獨享的,也就是說每個執行緒都有這麼一塊區域,因此,這兩個各自都有各自的程式計數器

這兩個之間是互不干擾的,也就是相當於有兩段程式碼在同時的進行,這就是多執行緒,關於Java虛擬機器的記憶體模型,可以參考我的《深入理解Java虛擬機器》。

那麼,我們自己能不能建立多個執行緒呢?當然也是可以的,我們可以任意的建立多個執行緒,只要我們當前的硬體環境能夠支援,我們可以任意建立很多個執行緒。

我們說,每一個執行緒就是一個順序執行流,“順序執行流”非常好理解,看著它像流水一樣往下執行,這就是一個流,那麼,它是怎麼執行的呢?它是按順序執行的,一個執行緒就是一個順序執行流,那麼所謂的多執行緒就是多個順序執行流。

然後我們接著說併發的問題,多執行緒和併發到底有什麼關係呢?併發就是並行的執行,是不是跟多執行緒非常的類似呀,那麼,多執行緒是不是就是併發呢?其實不是,從廣義上來說,我們可能就認為多執行緒就是併發,但是,實際上多執行緒不是併發,我們可以這麼去想。我們知道Java程式碼最終會被翻譯成位元組碼,那麼,位元組碼檔案裡面都是位元組碼指令,我們Java虛擬機器執行,其實執行的就是位元組碼指令。Java執行肯定是離不開Java虛擬機器的,那麼,我們想深入的研究併發,也會不斷的去了解Java虛擬機器的一些執行時過程,我們剛才說位元組碼,說原始碼會被編譯成位元組碼,那麼我們Java虛擬機器執行的就是位元組碼指令,那麼,它在執行過程中,是由誰執行的呢?其實,它最終又交給了我們的作業系統去執行,我們目前就先不管這些事,其實最終是執行在CPU上面的,那麼,比如說,我們說,我們當前這個CPU

也就是說,雙核四個執行緒,那麼,我們能不能建立5個執行緒呀?能不能建立6個執行緒?能不能建立100個執行緒?顯然是可以的。它其實並不是由CPU的核數來決定的,即使是就只有一個CPU核心,那麼,它同樣的也能夠建立多個執行緒,那麼,我們現在先不說多核的問題,就說一個CPU核心,那麼,一個CPU核心也能夠建立多個執行緒,那麼,多個執行緒也是同時在執行的,那麼,它是怎麼做到的呢?畫個圖解釋一下

假設這是一個爐子,那麼,這個爐子是幹什麼的呢?假設這個爐子是用來考燒餅的

假設這些是爐子上面放的燒餅。

這個爐子的下面,有一個火爐

假設這個爐子在不停的轉,那麼,當轉到火爐上面的時候,對應的這個火爐上面的燒餅才開始烤,那麼這個燒餅其實就是我們的執行緒,而,下面的這個火爐是我們的CPU

當爐子在轉的非常快的時候,我們說,任務的切換執行緒之間的切換時間就會非常的短,那麼,我們就會看起來像是在同時執行,但是,其實並不是在同時執行,它是在不停的切換的,就類似於,圖片切換的頻率非常高的時候,就成了動畫,就成了視訊,也是這個道理,執行緒任務切換的非常快的時候,那麼我們就認為它是在不間斷的執行的,這個原理其實也類似於我們的燈泡,燈泡其實也是在不停的閃的,我們看到燈泡一直亮,就是因為它閃的頻率非常的高,這就是多執行緒,多執行緒其實並不是多個執行緒一起執行而是執行緒之間因為切換的速度非常的快,所以,我們看起來像不間斷的執行

那麼,並行又是什麼呢?並行就不一樣了,並行表示的是多個任務同時執行,就是說,這麼多的燒餅在一塊烤,那怎麼做到的?有多個爐子就可以做到了。每個燒餅下面有一個爐子,這樣就能做到一塊烤了,這就是所謂的並行,那麼,併發和多執行緒之間其實通過這個例子就可以看的非常清楚了,多執行緒並不一定是併發,如果是併發執行,那麼肯定是多個執行緒在一塊執行,當然也未必,多個程序也是併發執行。

這就是多執行緒和併發之間的關係。