Java——進程和線程區別(糾正網上幾個常見的誤解)

1.什麼是進程?

當一個程序開始運行時,它就是一個進程,進程包括運行中的程序和程序所使用到的內存和系統資源。

進程由兩部分構成:進程內核對象,地址空間。

每個進程至少由三要素組成:程序塊、數據塊、進程控制塊

進程是系統進行資源分配的一個基本單位,是資源分配的最小單位。

進程只能通過通信共享

而一個進程又是由多個線程所組成的。

 

進程的執行

進程執行的時候通過進程控制塊找到入口進入執行,然後將要執行的線程進行壓棧及出棧

 

2.什麼是線程?

線程是系統調度的基本單位。

線程是程序中的一個執行流,每個線程都有自己的堆棧、局部變量和專有寄存器(棧指針、程序計數器等),但代碼區是共享的,即不同的線程可以執行同樣的函數。

線程也由兩部分組成:線程內核對象,操作系統用它來對線程實施管理。線程堆棧,用於維護線程在執行代碼時需要的所有函數參數和局部變量。

是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位,是程序執行的最小單位.

線程是一種操作系統對象,代表着一個進程中要被執行的代碼的路徑。

每個線程啓動會默認分配1mb的內存空間,隨着具體線程運行內容,會隨之更改。

一個線程至少一個棧幀

 

線程共享解析(糾正網上部分理解)

我們在main方法中創建一個int變量爲first,並創建兩個線程

此時相當於在主方法棧中創建兩個線程棧,如果把first傳入這兩個線程棧中的話,其實是給他們傳了一個副本過去(static同樣是如此),此時兩個線程棧中處理的first是不同的副本,所以各線程之間不會相互干擾。

而如果是傳給普通方法first,就是傳了個副本過去,各個棧幀分別處理自己的first,且最後不會同步。

那麼共享又是什麼意思呢?

意味着線程棧中對first屬性進行操作後,會把操作後的結果同步到主方法棧中。

3.二者之間的關係

(1)一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以併發執行.不同進程之間互不干擾,但是也可以對其他進程進行操作,只是這種操作往往也是藉助於操作系統實現。

(2)沒有線程的進程可以看做是單線程的,如果一個進程內有多個線程,則執行過程不是一條線的,而是多條線(線程)共同完成的;線程是進程的一部分,所以線程也被稱爲輕權進程或者輕量級進程。

(3)相對進程而言,線程是一個更加接近於執行體的概念,它可以與同進程中的其他線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列。

 

4.二者之間的區別

1.操作系統資源管理方式不同。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響。線程崩潰時,並不會造成整個進程崩潰,也不一定會影響到其他線程,除非惡性改變了線程之間共享的一些數據。

2.通信機制不同(獨立性)。正因爲進程之間互不干擾,相互獨立,進程的通信機制相對很複雜,譬如管道,信號,消息隊列,共享內存,套接字等通信機制,而屬於同一個進程的所有線程共享該進程的所有資源,通信機制很方便。。

3.包含關係。線程必定也只能屬於一個進程,而進程可以擁有多個線程而且至少擁有一個線程;這一點可以參照上文的第二小節。

4.程序結構不同。舉一個簡明易懂的列子:當我們使用進程的時候,我們不自主的使用if else嵌套來判斷pid,使得程序結構繁瑣,但是當我們使用線程的時候,基本上可以甩掉它,當然程序內部執行功能單元需要使用的時候還是要使用,所以線程對程序結構的改善有很大幫助。

5.執行過程不同。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

6.進程是不活潑的。進程從來不執行任何東西,它只是線程的容器。線程總是在某個進程環境中創建的,而且它的整個壽命期都在該進程中。

7.進程使用的系統資源比線程多得多。實際上,線程只有一個內核對象和一個堆棧,保留的記錄很少,因此需要很少的內存。進程切換時,耗費資源較大,效率要差一些。因此始終都應該設法用增加線程來解決編程問題,避免創建新的進程。但是許多程序設計用多個進程來實現會更好些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程(單核的情況)。

8.進程是程序的一次動態執行過程,它對應了從代碼加載、執行到執行完畢的一個完整過程,這個過程也是進程本身從產生、發展到消亡的過程。線程是比進程更小的執行單位。一個進程在其執行過程能夠中,可以產生 多個線程,形成多條執行線索。每條線索,即每個線程也有它自身的產生、存在和消亡過程,也是一個動態的概念。

 

5.如何選擇?

進程與線程的選擇取決以下幾點:

1、需要頻繁創建銷燬的優先使用線程,因爲對進程來說創建和銷燬一個進程代價是很大的。

2、線程的切換速度快,所以在需要大量計算,切換頻繁時用線程,還有耗時的操作使用線程可提高應用程序的響應

3、因爲對CPU系統的效率使用上線程更佔優,所以多機分佈用進程,多核分佈用線程;

4、並行操作時使用線程,如C/S架構的服務器端併發線程響應用戶的請求;

5、需要更穩定安全時,適合選擇進程;需要速度時,選擇線程。

6、在進程中進行費時的工作不會導致系統的掛起,但這會導致進程本身的掛起。所以,如果進程既要進行長期的工作,又要響應用戶的輸入,那麼它可以啓動一個線程來專門負責費時的工作,而主線程仍然可以與用戶進行交互。
 

 

6.創建線程和進程的時間開銷

線程執行開銷小,速度快,但不利於資源的管理和保護;

進程執行開銷大,穩定安全,利於資源的管理和保護。

在 Windows 中,進程創建的開銷不容忽視。所以Windows 編程中並不建議創建進程,如果你的程序架構需要大量創建進程,那麼最好是切換到 Linux 系統。

再次補充:如果你是寫服務器端應用的,其實在現在的網絡服務模型下,創建線程的開銷是可以忽略不計的,因爲現在一般流行的是按照 CPU 核心數量開進程或者線程,開完之後在數量上一直保持,進程與線程內部使用協程或者異步通信來處理多個併發連接,因而開進程與開線程的開銷可以忽略了。

 

淘寶雙十一爲什麼有時候會加載不出來?

因爲每個人的請求,服務器都分配線程處理,但是線程佔空間,人數足夠多的時候,便沒有足夠多的線程可以分配,所以請求被阻塞,每個請求又存儲只有1kb,阻塞多個請求並不會佔用過多的空間。當前面有線程處理完畢後,再分配線程給請求。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章