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
當爐子在轉的非常快的時候,我們說,任務的切換即執行緒之間的切換時間就會非常的短,那麼,我們就會看起來像是在同時執行,但是,其實並不是在同時執行,它是在不停的切換的,就類似於,圖片切換的頻率非常高的時候,就成了動畫,就成了視訊,也是這個道理,執行緒任務切換的非常快的時候,那麼我們就認為它是在不間斷的執行的,這個原理其實也類似於我們的燈泡,燈泡其實也是在不停的閃的,我們看到燈泡一直亮,就是因為它閃的頻率非常的高,這就是多執行緒,多執行緒其實並不是多個執行緒一起執行,而是執行緒之間因為切換的速度非常的快,所以,我們看起來像不間斷的執行。
那麼,並行又是什麼呢?並行就不一樣了,並行表示的是多個任務同時執行,就是說,這麼多的燒餅在一塊烤,那怎麼做到的?有多個爐子就可以做到了。每個燒餅下面有一個爐子,這樣就能做到一塊烤了,這就是所謂的並行,那麼,併發和多執行緒之間其實通過這個例子就可以看的非常清楚了,多執行緒並不一定是併發,如果是併發執行,那麼肯定是多個執行緒在一塊執行,當然也未必,多個程序也是併發執行。
這就是多執行緒和併發之間的關係。