1、簡介
NSThread類代表多線程類,一個NSThread對象就是一條線程
2、線程的創建和啓動
2.1 創建和啓動分開
// 創建線程 // 線程開啓後會自動調用self的run方法,參數是nil NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; // 啓動線程 [thread start];
2.2 創建的同時啓動
1.顯示創建
// 創建線程後自動調用self的download:方法,參數是@"http://www.baidu.com" [NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"http://www.baidu.com"];
2.隱式創建
// 後臺創建線程 [self performSelectorInBackground:@selector(download:) withObject:@"http://www.baidu.com"];
2.3 創建的方式比較
創建和啓動分開:可以更加細節的控制線程
創建的同時啓動:簡單快速,不能控制細節
3、主線程相關方法
4、線程的其他方法
// 是否爲主線程 - (BOOL)isMainThread; // 是否爲主線程 + (BOOL)isMainThread; // 獲得主線程 + (NSThread *)mainThread;
5、線程的狀態// 獲得當前線程 + (NSThread *)currentThread; // 線程的名字 - (NSString *)setName:(NSString *)name; - (NSString *)name; // 線程調度的優先級 // 優先級越高,線程執行的機會越多,範圍是0.0 - 1.0,默認0.5 + (double)threadPriority; + (BOOL)setThreadPriority:(double)p; - (double)threadPriority; - (BOOL)setThreadPriority:(double)p;
5.1 線程具有生命週期,生命週期內 ,在不同的階段,線程具有不同的狀態
就緒狀態:準備執行,但還沒開始執行
運行狀態:正在執行,也叫做執行狀態
阻塞狀態:暫停執行,也叫做暫停狀態
死亡狀態:結束執行,線程執行完畢後就會銷燬,無法重生
5.2 線程狀態的相關方法
// 開啓線程 - (void)start; // 暫停線程 + (void)sleepUntilDate:(NSDate *)date; + (void)sleepForTimeInterval:(NSTimeInterval)ti; // 強制銷燬線程 + (void)exit;
6、線程安全問題
6.1 資源共享
多條線程共享同一塊資源,即資源共享
多線程的資源共享,可能造成數據錯亂和數據安全的問題
6.2 線程安全問題
兩個支付寶賬號綁定同一張銀行卡,從銀行卡中提現到兩個支付寶
1.將設銀行卡內總額1000元,支付寶賬號分別叫做A、B,每個賬號提現200元
2.A讀取到1000元,準備提現但還沒有開始提現的時候,B讀取到1000元
3.A提現後,銀行卡剩餘800元,但是B讀取到的數值是1000元,而不是800元
4.B提現後,餘額依然是800元
5.銀行卡內實際餘額應該是600元,但是卻多出200元,這就是多線程造成的安全問題
6.3 解決方式
1.互斥鎖
1.1 關鍵代碼
@synchronized(鎖對象) {
// 需要鎖定的代碼
}
1.2 優缺點
優點:防止多條線程搶奪資源造成數據安全問題,同一份資源只要加一把鎖就夠了
缺點:需要消耗大量的CPU資源
1.3 使用前提
多條線程共享同一塊資源
2.原子屬性(atomic)
定義屬性的時候使用atomic,默認爲set方法加鎖
強調:原子屬性使用線程同步的技術,消耗系統資源,開發時,儘量使用nonatomic屬性
3.服務器處理
將搶奪資源的代碼和業務邏輯交給服務器處理,減小客戶端的壓力