前言
在上一篇章中我們主要探索了KVO的底層原理,和實作程序,也學習了自定義KVO的實作,那么本篇就開啟了大家心心念念的多執行緒了,其實多執行緒相關的使用方式,和一些概念的文章并不少,也是面試中基本是必問的內容,那么今天我們就一起來總結一些多執行緒的一些基本概念,權當回顧一下😄
1.執行緒的定義
-
a.執行緒是行程的基本執?單元,?個行程的所有任務都在執行緒中執?
-
b.行程要想執?任務,必須得有執行緒,行程?少要有?條執行緒
-
c.程式啟動會默認開啟?條執行緒,這條執行緒被稱為主執行緒或UI執行緒
2.行程的定義
-
a.行程是指在系統中正在運?的?個應?程式
-
b.每個行程之間是獨?的,每個行程均運?在其專?的且受保護的記憶體空間內
-
c.通過活動監視器(全域搜索活動監視器即可)可以查看Mac系統中所開啟的行程
3.兩者的關系
地址空間:同?行程的執行緒共享本行程的地址空間,?行程之間則是獨?的地址空間,
資源擁有:同?行程內的執行緒共享本行程的資源,如記憶體、I/O、cpu等,但是行程之間的資源是獨?的,
-
a.?個行程崩潰后,在保護模式下不會對其他行程產?影響,但是?個執行緒崩潰整個行程都死掉,所以多行程要?多執行緒健壯,
-
b.行程切換時,消耗的資源?,效率?,所以涉及到頻繁的切換時,使?執行緒要好于行程,同樣如果要求同時進?并且?要共享某些變數的并發操作,只能?執行緒不能?行程,
-
c.執?程序:每個獨?的行程有?個程式運?的??、順序執?序列和程式??,但是執行緒不能獨?執?,必須依存在應?程式中,由應?程式提供多個執行緒執?控制,
-
d.執行緒是處理器調度的基本單位,但是行程不是,
-
e.執行緒沒有地址空間,執行緒包含在行程地址空間中,
4.多執行緒的原理

如圖所示,多執行緒的原理其實就是CPU快速的在多個執行緒之間進行快速切換,而并不是我們想象的多個執行緒同時執行,只不過因為CPU在切換調度執行緒的速度很快,導致我們感覺像是在同時執行,也因此,如果執行緒數過多就會非常消耗CPU資源,影響執行效率,在我們現實開發中,一般也會針對耗時的操作,另開執行緒進行處理,從而避免主執行緒的阻塞
總結:
-
時間片:CPU在多個任務直接進?快速的切換,這個時間間隔就是時間?,(單核CPU)同?時間,CPU只能處理1個執行緒,換?之,同?時間只有 1 個執行緒在執?
-
多執行緒同時執?:是CPU快速的在多個執行緒之間的切換,CPU調度執行緒的時間?夠快,就造成了多執行緒的同時執?的效果
-
如果執行緒數?常多,CPU會在N個執行緒之間切換,消耗?量的CPU資源,每個執行緒被調度的次數會降低,執行緒的執?效率降低
多執行緒技術方案

5.多執行緒的優缺點
優點
-
a.能適當提?程式的執?效率
-
b.能適當提?資源的利?率(如CPU,記憶體)
-
c.執行緒上的任務執?完成后,執行緒會?動銷毀
缺點
-
a.開啟執行緒需要占??定的記憶體空間(默認情況下,每?個執行緒都占512KB)
-
b.如果開啟?量的執行緒,會占??量的記憶體空間,降低程式的性能
-
c.執行緒越多,CPU在調?執行緒上的開銷就越?
-
d.程式設計更加復雜,?如執行緒間的通信、多執行緒的資料共享
6.執行緒的生命周期

New:就是剛通過創建出來的執行緒;
Runnable:就是呼叫的執行緒的start方法后,這時候執行緒處于等待CPU分配資源階段,誰先搶的CPU資源,誰開始執行;
Running:當就緒的執行緒被調度并獲得CPU資源時,便進入運行狀態,run方法定義了執行緒的操作和功能;
Blocked:在運行狀態的時候,可能因為某些原因導致運行狀態的執行緒變成了阻塞狀態,比如sleep、等待同步鎖,執行緒就從可調度執行緒池移出,處于了阻塞狀態,這個時候sleep到時、獲取同步鎖,此時會重新添加到可調度執行緒池,喚醒的執行緒不會立刻執行run方法,它們要再次等待CPU分配資源進入運行狀態;
Dead:如果執行緒正常執行完畢后或執行緒被提前強制性的終止或出現例外導致結束,那么執行緒就要被銷毀,釋放資源,
7.執行緒池

執行步驟對應如下:
-
1.當有任務進來時,執行緒池先判斷如果正在運行的執行緒數量小于核心執行緒數,那么馬上創建核心執行緒運行這個任務;
-
2.如果正在運行的執行緒數量大于或等于核心執行緒數,那么將這個任務放入佇列;
-
3.如果這時候佇列滿了,而且正在運行的執行緒數量小于最大執行緒數,那么還是要創建非核心執行緒立刻運行這個任務;
-
4.如果佇列滿了,而且正在運行的執行緒數量大于或等于最大執行緒數,那么執行緒池飽和策略將進行處理,
飽和策略
-
1.AbortPolicy直接拋出RejectedExecutionExeception例外來阻?系統正常運?
-
2.CallerRunsPolicy將任務回退到調?者
-
3.DisOldestPolicy丟掉等待最久的任務
-
4.DisCardPolicy直接丟棄任務
這四種拒絕策略均實作的RejectedExecutionHandler接?
8.互斥鎖與自旋鎖
在多執行緒中,因為在同一個行程中,資源是共享的,所以多執行緒必然存在著資源的競爭,那么就引入了鎖的概念,
互斥鎖
最常使用于執行緒同步的鎖;標記用來保證在任一時刻,只能有一個執行緒訪問該物件,同一執行緒多次加鎖操作會造成死鎖;臨界區和互斥量都可用來實作此鎖,通常情況下鎖操作失敗會將該執行緒睡眠等待鎖釋放時被喚醒,
互斥鎖小結
-
1.保證鎖內的代碼,同一時間,只有一條執行緒能夠執行
-
2.互斥鎖的鎖定范圍,應該盡量小,鎖定范圍越大,效率越差
互斥鎖引數
-
1.能夠枷鎖的任意NSObject物件
-
2.鎖物件一定要保證所有執行緒都能夠訪問
-
3.如果代碼中只有一個地方需要枷鎖,大多都使用self,這樣可以避免單獨再創建一個鎖物件
自旋鎖
一種用于保護多執行緒共享資源的鎖,與一般互斥鎖不同之處在于當自旋鎖嘗試獲取鎖時以忙等待的形式不斷地回圈檢查鎖是否可用,當上一個執行緒的任務沒有執行完畢的時候(被鎖住),那么下一個執行緒會一直等待(不會睡眠),當上一個執行緒的任務執行完畢,下一個執行緒會立即執行,
區別(取自同期優秀LGPerson總結😄)
自旋鎖會忙等,所謂忙等,即在訪問被鎖資源時,呼叫者執行緒不會休眠,而是不停回圈在那里,直到被鎖資源釋放鎖,
互斥鎖會休眠,所謂休眠,即在訪問被鎖資源時,呼叫者執行緒會休眠,此時cpu可以調度其他執行緒作業,直到被鎖資源釋放鎖,此時會喚醒休眠執行緒,
自旋鎖優缺點
優點在于,因為自旋鎖不會引起呼叫者睡眠,所以不會進行執行緒調度,CPU時間片輪轉等耗時操作,所有如果能在很短的時間內獲得鎖,自旋鎖的效率遠高于互斥鎖,
缺點在于,自旋鎖一直占用CPU,他在未獲得鎖的情況下,一直運行自旋,所以占用著CPU,如果不能在很短的時間內獲得鎖,這無疑會使CPU效率降低,自旋鎖不能實作遞回呼叫,
9.atomic與nonatomic 的區別
1.OC在定義屬性時有nonatomic和atomic兩種選擇,默認為atomic屬性
- atomic:原子屬性,為setter方法加自旋鎖(即為單寫多讀)
- nonatomic:非原子屬性,不會為setter方法加鎖
2.nonatomic和atomic的對比
- atomic:執行緒安全,需要消耗大量的資源;
- nonatomic:非執行緒安全,適合記憶體小的移動設備,
iOS開發的建議
- 如非需搶占資源的屬性(如購票,充值),所有屬性都宣告為nonatomic,
- 盡量避免多執行緒搶奪同一塊資源,
- 盡量將加鎖、資源搶奪的業務邏輯交給服務器端處理,減小移動客戶端的壓力,
10.執行緒和Runloop的關系
-
1.runloop與執行緒是??對應的,?個runloop對應?個核?的執行緒,為什么說是核?的,是因為runloop是可以嵌套的,但是核?的只能有?個,他們的關系保存在?個全域的字典?,
-
2.runloop是來管理執行緒的,當執行緒的runloop被開啟后,執行緒會在
執行完任務后進入休眠狀態,有了任務就會被喚醒去執行任務 -
3.runloop在第一次獲取時被創建,在執行緒結束時被銷毀
-
4.對于主執行緒來說,runloop在程式一啟動就默認創建好了
-
5.對于子執行緒來說,runloop是懶加載的,只有當我們使用的時候才會創建,所以在子執行緒用定時器要注意:確保子執行緒的runloop被創建,不然定時器不會回呼
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/292528.html
標籤:其他
