Java 多線程(1) 多線程有什麼用?

搜索關於線程相關知識的時候,在知乎上看到的這個答案還是很形象的。


問題:多線程有什麼用?

回答一

這麼解釋問題吧:

1。單進程單線程:一個人在一個桌子上喫菜。
2。單進程多線程:多個人在同一個桌子上一起喫菜。
3。多進程單線程:多個人每個人在自己的桌子上喫菜。

多線程的問題是多個人同時喫一道菜的時候容易發生爭搶,例如兩個人同時夾一個菜,一個人剛伸出筷子,結果伸到的時候已經被夾走菜了。。。此時就必須等一個人夾一口之後,在還給另外一個人夾菜,也就是說資源共享就會發生衝突爭搶。


1。對於 Windows 系統來說,【開桌子】的開銷很大,因此 Windows 鼓勵大家在一個桌子上喫菜。因此 Windows 多線程學習重點是要大量面對資源爭搶與同步方面的問題。


2。對於 Linux 系統來說,【開桌子】的開銷很小,因此 Linux 鼓勵大家儘量每個人都開自己的桌子喫菜。這帶來新的問題是:坐在兩張不同的桌子上,說話不方便。因此,Linux 下的學習重點大家要學習進程間通訊的方法。

--
補充:有人對這個開桌子的開銷很有興趣。我把這個問題推廣說開一下。

開桌子的意思是指創建進程。開銷這裏主要指的是時間開銷。
可以做個實驗:創建一個進程,在進程中往內存寫若干數據,然後讀出該數據,然後退出。此過程重複 1000 次,相當於創建/銷燬進程 1000 次。在我機器上的測試結果是: 
UbuntuLinux:耗時 0.8 秒 
Windows7:耗時 79.8 秒 
兩者開銷大約相差一百倍。

這意味着,在 Windows 中,進程創建的開銷不容忽視。換句話說就是,Windows 編程中不建議你創建進程,如果你的程序架構需要大量創建進程,那麼最好是切換到 Linux 系統。

大量創建進程的典型例子有兩個,一個是 gnu autotools 工具鏈,用於編譯很多開源代碼的,他們在 Windows 下編譯速度會很慢,因此軟件開發人員最好是避免使用 Windows。另一個是服務器,某些服務器框架依靠大量創建進程來幹活,甚至是對每個用戶請求就創建一個進程,這些服務器在 Windows 下運行的效率就會很差。這"可能"也是放眼全世界範圍,Linux 服務器遠遠多於 Windows 服務器的原因。

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

另外一種新的開銷被提上日程:核心切換開銷。

現代的體系,一般 CPU 會有多個核心,而多個核心可以同時運行多個不同的線程或者進程。

當每個 CPU 核心運行一個進程的時候,由於每個進程的資源都獨立,所以 CPU 核心之間切換的時候無需考慮上下文。

當每個 CPU 核心運行一個線程的時候,由於每個線程需要共享資源,所以這些資源必須從 CPU 的一個核心被複制到另外一個核心,才能繼續運算,這佔用了額外的開銷。換句話說,在 CPU 爲多核的情況下,多線程在性能上不如多進程。

因而,當前面向多核的服務器端編程中,需要習慣多進程而非多線程。



回答二:很多人答案說的是操作系統提供的多進程而不是單個程序內的多線程。 

多線程使得程序內部可以分出多個線程來做多件事情,而不會造成程序界面卡死。比如迅雷等多線程下載工具就是典型的多線程。一個下載任務進來,迅雷把文件平分成10份,然後開10個線程分別下載。這時主界面是一個單獨的線程,並不會因爲下載文件而卡死。而且主線程可以控制下屬線程,比如某個線程下載緩慢甚至停止,主線程可以把它強行關掉並重啓另外一個線程。 

另外就是一些程序的打印功能,比如記事本、Adobe Reader,打印的時候就只能打印,無法在主界面進行操作,而Word就有“後臺打印”的功能,點了打印命令之後,還可以回到主界面進行修改、保存等操作。 

另外多線程除了並行完成一些任務以外,還有生產者-消費者模式。比如Windows命令行下在某個硬盤根目錄執行一個"dir/s | more"命令,前一條顯示硬盤裏的所有文件,要執行很久才能執行得完,後面那條命令會把前面命令的輸出分屏顯示出來。但是執行整條命令時,會立刻有顯示,也就是說,前面一條命令輸出滿一頁內容到緩衝區,more命令就把緩衝區封死了,等用戶敲了一個鍵顯示下一屏的時候,more命令把緩衝區的內容取出並清空,前面的命令才能輸出下一屏到緩衝區。這樣的多線程使得整條命令不用等待前面的命令全部執行完才能執行下一條命令。 

多線程和多進程的區別。平常指的多進程是操作系統下同時運行多個進程,比如Word和Excel同時打開,並且可以並行地同時執行一些操作。這種多進程和多線程沒什麼好比較的。可以比較的是同一個程序裏的多線程和多進程。 

多線程因爲在同一個進程裏,所以可以共享內存和其他資源,比如迅雷裏10個線程一齊下載一個文件,這個文件是由進程打開的,然後10個線程都可以往裏寫入東西。如果是10個進程就不行了,操作系統不允許一個文件由兩個進程同時寫入。另外,Chrome就是一個典型的多進程程序,裏面每個標籤頁、擴展、插件都是單獨的進程,各自獨佔資源,相互隔離,一個進程出錯死掉只會影響一個頁面或者插件,再也不會出現Flash插件出錯崩潰導致整個瀏覽器崩潰的情況了。


參考:http://www.zhihu.com/question/19901763


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