java多線程(一)-概述

最近這段在看java多線程編程方面的東西。因此特寫了幾篇文章,來總結和回顧一下本身所學習到的相關知識。由於水平有限,文章中總結不全面甚至理解錯誤的地方,歡迎讀者指點批評。java

咱們平時所接觸到的程序,都是順序編程。
順序編程的意思是,程序中的全部事物在任意時刻都只能執行一個步驟(包括那些代碼當中的順序結構,選擇結構,循環結構),
順序編程知足了咱們可以碰到的大部分問題,可是有些問題,僅僅依靠順序編程是不夠的,舉個例子,一個帶界面的音樂播放程序,在播放歌曲的同時也能及時的響應用戶在界面上進行的的按鍵操做(好比點擊 下一曲 按鈕)。那麼此時順序編程就不合適了,由於這是須要兩件同時執行的事情,若是採用順序編程,爲了及時響應按鍵操做,咱們須要在代碼的不少地方都要加上檢測按鍵狀態的代碼。而這種場景下就須要併發編程了。linux

併發編程 有不一樣的實現方式。 好比 多進程模式,多線程模式等。
而最多見也最直接的就是 操做系統級別使用的進程,所謂 進程就是運行在它本身的地址空間內的自包容的程序。好比,能夠在電腦上,同時並行進行幾個不一樣的任務,qq和人聊天,酷狗播放器播放音樂,而後瀏覽器下着文件,這就是三個不一樣的進程,這三個進程彼此之間相互隔絕,不受其餘進程影響。 git

而對於同一個進程,也能夠採用多線程開發技術,使得一個程序內部多個線程能夠並行運行。程序員

固然,對於單核cpu,咱們說計算機能在同一個時間點並行運行多進程或多線程。它們實際上都不是真正意義上的同一個時間點,只不過cpu切換速度極快,操做系統將cpu時間切片,分配給不一樣的任務。雖然看起來每一個任務在執行過程當中都是有時運行有時中止,可是鑑於cpu執行的速度極高,因此在咱們使用者看來,那都是連續的,不間斷的。這幾個不一樣的任務就像同時並行運行同樣。github

而伴隨着多核cpu的出現,幾個核同時運行,這個時候,它們纔有多是在真正的同一個時間點並行運行。編程


而多線程,由於會對相同的內存空間進行併發讀寫操做,因此它們更加複雜。
解釋一下這句話,仍是 回到剛纔舉的那個例子,在一臺電腦上,同時運行幾個不一樣的任務。qq和人聊天,酷狗播放器播放音樂,而後瀏覽器下着文件。咱們知道,不管什麼程序,歸根結底編譯到了最底層,那就是0和1。由於cpu只認識0和1,若是把0和1轉化爲容易閱讀的語言,那就是彙編語言。看過彙編的應該知道,相似 什麼mov ax,bx 之類的語句都是直接操做寄存器或內存地址的。那麼這個時候問題就來了,酷狗播放器,qq,瀏覽器這三個程序,編譯到了彙編層次,那麼也會直接操做寄存器和內存地址,那麼爲何他們這些程序之間不衝突呢?緣由就是由於 其實他們這個地址之類的,都是虛擬內存地址。酷狗播放器和qq編譯成彙編語言以後,他們的內存地址都是虛擬的,因此哪怕這兩個程序在彙編層面都操做同一個內存地址,也不會彼此衝突。這中間的功勞就是屬於操做系統和cpu。操做系統在運行這兩個進程時,會和cpu一塊兒起做用,把他們的虛擬地址空間轉換爲實際的地址空間。其實說白了,就是 酷狗播放器,qq,瀏覽器在編寫他們各自的代碼的時候。根本不會考慮彙編層面上,寄存器,內存地址之類的問題。他們只須要寫好本身程序自己的代碼就好了。至於那些多個進程怎麼運行之類的複雜問題的,上層開發的程序員們是不用關心的。瀏覽器

而多線程,他們歸根到底仍是屬於同一個進程,所以多個不一樣線程仍是對於同一內存空間進行操做,因此多線程更復雜,更容易出問題。服務器

對於多進程,某個進程崩潰了,那麼對其餘進程 沒啥影響,可是對於多線程,某個線程崩潰了,它所屬的這個進程也會受到直接影響。網絡

固然,咱們在說不一樣的進程在運行的時候,都屬於各自幹好本身的事情,中間不會發生什麼聯繫。這樣就避免了相互干擾。不過操做系統固然也提供了進程間通訊機制(IPC),好比linux的 管道,信號,套接字之類的。多線程

 

而從表面上看,若是一樣一個任務(進程),分解成多個線程來執行,和單獨一個線程來執行,理論上前者的開銷應該是更大的,緣由很簡單,執行多線程會增長 上下文切換的代價。可是實際上,多線程之因此更快,有兩個主要因素。
(1)阻塞。程序由於程序控制以外的某些因素(好比I/0)而致使不能繼續執行,cpu是如此寶貴的資源,若是cpu一直處於等待狀態,那豈不是一種很大的浪費。拿i/o操做來講,cpu的執行速度極高,它的時間都是按照納秒爲單位的,可是執行程序所須要的資源或數據確每每在內存,硬盤,乃至網絡服務器上,它們的速度相對於cpu那就太慢,甚至極慢。若是是順序編程,在這種狀況下,cpu只能乾等着,沒辦法繼續幹活。那麼這種狀況下,多線程就變的頗有必要了。此時cpu能夠切換執行另外一個任務,那麼就不用幹等着其中一個線程。

(2)多核cpu的出現,在最初的時候cpu都是單核的,可是到如今四核八核都很廣泛的狀況下,若是是順序編程只能在某一個核上運行。找人完成一件任務,一我的單獨幹,和8我的協助幹,雖而後者會須要花費更多的組織和協調的耗費,可是明顯後者幹活比前者快。

多線程編程將一個大的程序(任務/進程)劃分爲多個分離的,獨立運行的線程(子任務),一個線程就是該進程中的 一個單一的順序控制流,每一個線程雖然沒有獨立的地址空間(由於只有進程纔有),可是各個線程有本身的堆棧和局部變量。而在線程自己來看,就像它單獨佔有cpu同樣。雖然底層機制是操做系統切分了cpu的時間,給它分配了這一段的時間。不過上層開發的程序員是不用關心這些的,因此這種線程模型方便了上層開發者。

 

-------
做者: www.yaoxiaowen.com
github: https://github.com/yaowen369

相關文章
相關標籤/搜索