深刻理解併發編程 -- 多線程(二)底層運行原理、線程狀態

併發編程 -- 多線程底層運行原理、線程狀態

做者 : Stanley 羅昊html

多線程 -- 併發編程(一) : https://www.cnblogs.com/StanleyBlogs/p/10890906.html編程

轉載請註明出處和署名,謝謝!多線程

多線程底層執行原理

說道底層運行,那麼是否是就是須要依靠CPU啊;併發

那,各位以前有沒有聽過一句話叫作,一個CPU在同一個時間片只能執行一個程序測試

什麼意思呢?spa

就是,你的程序是否是都運行在一個CPU上啊,那你真正一個CPU在同一個時間片裏是否是隻能執行一個程序呀,那這個程序究竟要執行那個程序,是否是就須要經過線程之間時間片的一個爭搶;線程

時間片:微小的時間段;3d

多線程說白了就是時間片的爭奪,那個線程獲取了時間片,就執行那個線程的代碼;htm

假設,t1線程先得到時間片,那麼,t1線程就優先執行;blog

可是,它不可能拿着那個時間片不放吧,由於在CPU執行的過程當中,底層運用輪循制的;

多線程執行的時候,CPU分配時間片是採起輪循的方式進行分配的;

就是輪流,有點像值日的時候,輪流值日同樣;

那,CPU在分配時間片的時候,第一個t1先搶佔到了以後,他先執行了一段時間以後,CPU把這個t1執行完了之後,CPU是否是接着把時間片分配給t2去執行了;

那事實上,也是t2也在去搶佔時間片

t1執行完畢後,那麼,CPU就將迎來新的一輪爭奪,這個時候t2搶到了,就開始執行t2的代碼;

這就是多線程的底層執行原理;

多線程它在本質上運行的時候,他是同時執行的,仍是輪流執行的呢?

確定不是同時執行的,也就是否是咱們常說的併發執行;那在大家看來,實際就是宏觀上你來看就是同時執行,可是在微觀上是否是的;

線程的狀態

線程總共有五種狀態;

第一個狀態 新建狀態

新建狀態,就是你新建一個線程是的狀態,也就是你新建了一個線程但尚未啓動時的狀態;

當線程執行start方法的時候,就會進入就緒狀態;

第二個狀態 就緒狀態

進入就緒狀態的時候,事實上就是準備搶佔CPU的時間片;

一旦搶佔到了CPU的時間片它就會當即進入運行狀態;

第三個狀態 運行狀態

當線程搶佔到了CPU時間片的時候,它纔會運行,因此第三個狀態是,運行狀態;

在它的運行狀態中,還有可能執行一個代碼,Throad.sleep();睡眠;

就是在你執行的時候,忽然讓你睡眠了,我都讓你這個線程睡眠了,你還有必要去爭奪這個CPU資源嗎?

就確定沒有必要再去爭奪這個CPU資源了,那這個時候你就須要釋放CPU啊,對不對,你釋放以後,你下次再運行的時候,你就須要從新獲取CPU的時間片,因此這種狀態就叫作堵塞狀態;

第四個狀態 堵塞狀態與sleep方法

想讓線程阻塞,最經常使用的方式就是使用sleep,用sleep這個方法,可使運行中的線程回到就緒狀態;

由於它須要從新搶佔CPU資源的,因此,sleep狀態的最終目的是讓改線程回到就讀狀態;

就好比,我如今想讓這個線程,進我想讓它每次進入run方法中的for循環打印裏寫一個睡眠,一遍循環遍歷輸出,一邊睡眠看會發生什麼:

我在run方法中業務寫完後,咱們測試一下該線程:

在上圖中,能夠發現,我同時調用了兩次start方法,說明,我執行了兩次我一次性開啓了兩次線程,而且執行了兩次,咱們看看會不會出現交替執行的狀況:

從輸出結果來看,確實交替執行了而且,是倆倆執行的:

每過一秒,就會執行一次:

我就不繼續演示了;

因此,咱們從中能夠看出,無論哪一個線程過來,t1也好t2也好,執行的時候,均睡眠一秒鐘,睡眠完一秒鐘以後,誰先醒了,誰就繼續向下執行,這個就是到點天然醒的;

也可使用join來形成線程堵塞;

join

剛剛,咱們在上面介紹了sleep,咱們來看看join;

join():是線程加入

它底層執行的是,當你在執行一個線程的時候,若是遇到其餘線程加入,則會先執行加入的線程,直到的加入的線程執行完成,纔會繼續執行原來線程的任務;

什麼意思呢?

就是說,仍是上面那個t1,與t2的例子,那假設說,t1在執行的過程當中,忽然遇到了一個代碼t2.join,這時候,就會在這個時間片,優先執行t2的線程;

join()方法能夠給一個參數,參數表明執行的毫秒; 

第五個狀態 死亡狀態

線程執行完了,或因異常退出了,都會結束生命週期,這就是死亡狀態;

相關文章
相關標籤/搜索