1、多線程的概念
2、多線程的執(zhí)行原理
3、多線程的優(yōu)缺點(diǎn)
4、什么是主線程?
5、iOS中有哪些多線程的技術(shù)方案
? ? 5.1pthread的簡單使用
? ? 5.2NSThread的簡單使用
6、線程的狀態(tài)
7、多線程操作共享資源的問題
? ? 7、1資源搶奪問題的分析和解決
? ? 7、2什么是互斥鎖,互斥鎖的原理
8、什么是原子屬性?
9、關(guān)于互斥鎖和原子鎖
10、補(bǔ)充
1、多線程的概念
要了解什么是多線程,首先必須知道什么是線程?什么是進(jìn)程?
進(jìn)程
進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序
每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用的且受保護(hù)的內(nèi)存空間內(nèi)
通過“活動(dòng)監(jiān)視器”可以查看Mac系統(tǒng)中所開啟的進(jìn)程
線程
1個(gè)進(jìn)程可以有多個(gè)線程組成(1個(gè)進(jìn)程至少要有1個(gè)線程)
線程是進(jìn)程的基本執(zhí)行單元,一個(gè)進(jìn)程的所有任務(wù)都在線程中執(zhí)行
2、多線程的執(zhí)行原理
a. (單核CPU)同一時(shí)間,cpu只能處理1個(gè)線程,只有1個(gè)線程在執(zhí)行任務(wù)
b.多線程同時(shí)執(zhí)行:是CPU快速的在多個(gè)線程之間的切換
c.cpu調(diào)度線程的時(shí)間足夠快,就造成了多線程的"同時(shí)"執(zhí)行的假象
d. 如果線程數(shù)非常多,cpu會(huì)在n個(gè)線程之間切換,消耗大量的cpu資源
e. 每個(gè)線程被調(diào)度的次數(shù)會(huì)降低,線程的執(zhí)行效率降低
3、多線程的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
能適當(dāng)提高程序的執(zhí)行效率
能適當(dāng)提高資源的利用率(cpu,內(nèi)存)
線程上的任務(wù)執(zhí)行完成后,線程會(huì)自動(dòng)銷毀
缺點(diǎn)
開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下,每一個(gè)線程都占512KB)
如果開啟大量的線程,會(huì)占用大量的內(nèi)存空間,降低程序的性能
線程越多,cpu在調(diào)用線程上的開銷就越大
程序設(shè)計(jì)更加復(fù)雜,比如多線程的數(shù)據(jù)共享、線程間的通信
下圖為官方文檔中的一個(gè)截圖,需要注意的是,在iOS中主線程的??臻g也是512KB,通過控制臺的打印我們也可以很容易得出,這個(gè)可能是Xcode文檔更新不太及時(shí)。
在iOS開發(fā)中,需要用到的多線程技術(shù)。
4、什么是主線程?
一個(gè)程序運(yùn)行后,默認(rèn)會(huì)開啟1個(gè)線程,稱為“主線程”或“UI線程”
主線程一般用來? 刷新UI界面 ,處理UI事件(比如:點(diǎn)擊、滾動(dòng)、拖拽等事件)
主線程使用注意
別將耗時(shí)的操作放到主線程中
耗時(shí)操作會(huì)卡住主線程,嚴(yán)重影響UI的流暢度,給用戶一種卡的壞體驗(yàn)
5、iOS中有哪些多線程的技術(shù)方案
在iOS開發(fā)中,需要用到的多線程技術(shù)。
5.1pthread的簡單使用
代碼:
? ? pthread_t shabi;
? ? // 創(chuàng)建一個(gè)子線程
? ? int result = pthread_create(&shabi, NULL, demo, NULL);
? ? if (result == 0) {
? ? ? ? NSLog(@"創(chuàng)建成功,%@",[NSThread currentThread]);? ?
? ? }
? ? else{
? ? ? ? NSLog(@"失敗");
? ? }
// 這個(gè)方法是子線程執(zhí)行的
void *demo(void *pram)
{
? ? NSLog(@"創(chuàng)建成功,%@",[NSThread currentThread]);
? ? return NULL;
}
5.2NSThread的簡單使用
方式1
? ? NSThread *thread = [[NSThread alloc] initWithTarget:selfselector:@selector(demo:) object:nil];
[thread start];
方式2
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:selfwithObject:nil];
方式3
? ? [self performSelectorInBackground:@selector(demo:) withObject:nil];
6、線程的狀態(tài)
在iOS開發(fā)中,需要用到的多線程技術(shù)。
6、1控制線程的狀態(tài)
啟動(dòng)線程
- (void)start;
線程進(jìn)入就緒狀態(tài),當(dāng)線程執(zhí)行完畢后自動(dòng)進(jìn)入死亡狀態(tài)。
暫停(阻塞)線程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
線程進(jìn)入阻塞狀態(tài)
停止線程
+ (void)exit;
線程進(jìn)入死亡狀態(tài)
注意:一旦線程停止(死亡)了,就不能再次開啟任務(wù)
6、2線程的屬性
線程名稱
設(shè)置線程名稱可以當(dāng)線程執(zhí)行的方法內(nèi)部出現(xiàn)異常的時(shí)候記錄 異常和當(dāng)前線程
線程優(yōu)先級
內(nèi)核調(diào)度算法在決定該運(yùn)行哪個(gè)線程時(shí),會(huì)把線程的優(yōu)先級作為考量因素,較高優(yōu)先級的線程會(huì)比較低優(yōu)先級的線程具有更多的運(yùn)行機(jī)會(huì)。較高優(yōu)先級不保證你的線程具體執(zhí)行的時(shí)間,只是相比較低優(yōu)先級的線程,它更有可能被調(diào)度器選擇執(zhí)行而已。
7、多線程操作共享資源的問題
共享資源
資源 : 一個(gè)對象、一個(gè)變量、一個(gè)文件
共享資源 : 全局的對象,變量,文件.可以被其他對象訪問的資源
在多線程的環(huán)境下,1塊資源可能會(huì)被多個(gè)線程共享,也就是多個(gè)線程可能會(huì)操作同一塊資源
當(dāng)多個(gè)線程操作同一塊資源時(shí),很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問題,數(shù)據(jù)有可能丟失,有可能增加,有可能錯(cuò)亂.
7、1資源搶奪問題的分析和解決
問題分析:
在iOS開發(fā)中,需要用到的多線程技術(shù)。
問題解決:
在iOS開發(fā)中,需要用到的多線程技術(shù)。
7、2什么是互斥鎖,互斥鎖的原理
互斥鎖使用
@synchronized(鎖對象) { // 需要鎖定的代碼? }
互斥鎖
能有效防止因多線程搶奪資源造成的數(shù)據(jù)安全問題
相關(guān)專業(yè)術(shù)語:線程同步
線程同步的意思是:多條線程按順序地執(zhí)行任務(wù)
互斥鎖,就是使用了線程同步技術(shù)
互斥鎖原理
每一個(gè)對象(NSObject)內(nèi)部都有一個(gè)鎖(變量),當(dāng)有線程要進(jìn)入synchronized到代碼塊中會(huì)先檢查對象的鎖是打開還是關(guān)閉狀態(tài),默認(rèn)鎖是打開狀態(tài)(1),如果是線程執(zhí)行到代碼塊內(nèi)部 會(huì)先上鎖(0)。如果鎖被關(guān)閉,再有線程要執(zhí)行代碼塊就先等待,直到鎖打開才可以進(jìn)入。
線程執(zhí)行到synchronized
i. 檢查鎖狀態(tài) 如果是開鎖狀態(tài)(1)轉(zhuǎn)到ii? 如果上鎖(0)轉(zhuǎn)到v
ii. 上鎖(0)
iii. 執(zhí)行代碼塊
iv. 執(zhí)行完畢 開鎖(1)
v.? 線程等待(就緒狀態(tài))
加鎖后程序執(zhí)行的效率比不加鎖的時(shí)候要低,因?yàn)橐€程要等待鎖,但是鎖保證了多個(gè)線程同時(shí)操作全局變量的安全性
8、什么是原子屬性?
屬性中的修飾符
nonatomic 非原子屬性
atomic? 原子屬性(線程安全),針對多線程設(shè)計(jì)的,默認(rèn)值
保證同一時(shí)間只有一個(gè)線程能夠?qū)懭?但是同一個(gè)時(shí)間多個(gè)線程都可以取值)
單寫多讀:單個(gè)線程寫入,多個(gè)線程可以讀取
atomic? 本身就有一把鎖(自旋鎖)
nonatomic和atomic對比
atomic:線程安全,需要消耗大量的資源
nonatomic:非線程安全,適合內(nèi)存小的移動(dòng)設(shè)備
iOS開發(fā)的建議
所有屬性都聲明為nonatomic
盡量避免多線程搶奪同一塊資源
盡量將加鎖、資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器端處理,減小移動(dòng)客戶端的壓力
9、關(guān)于互斥鎖和原子鎖
互斥鎖
如果發(fā)現(xiàn)其他線程正在執(zhí)行鎖定代碼,線程會(huì)進(jìn)入休眠(就緒狀態(tài)),等其它線程時(shí)間片到打開鎖后,線程會(huì)被喚醒(執(zhí)行)
自旋鎖
如果發(fā)現(xiàn)有其它線程正在鎖定代碼,線程會(huì)用死循環(huán)的方式,一直等待鎖定的代碼執(zhí)行完成 自旋鎖更適合執(zhí)行不耗時(shí)的代碼
10、補(bǔ)充
線程安全
多個(gè)線程同時(shí)操作共享資源是不安全的,多個(gè)線程同時(shí)操作一個(gè)全局變量
線程安全:在多個(gè)線程進(jìn)行讀寫操作時(shí),仍然能夠保證數(shù)據(jù)的正確
主線程(UI線程)
幾乎所有UIKit類庫提供的類都是線程不安全的,所有更新UI的操作都在主線程上執(zhí)行
所有包含NSMutable的類都是線程不安全的