1. 程式人生 > >iOS開發-多執行緒NSThread的基本介紹和使用

iOS開發-多執行緒NSThread的基本介紹和使用

今天給同學講解一下多執行緒的入門瞭解和使用那麼廢話不多說直接上程式碼~

  • NSThread建立和啟動執行緒
  • NSThread其他用法
  • 其他建立執行緒方式
  • 執行緒的狀態介紹
  • 控制執行緒狀態
  • 多執行緒的安全隱患
  • 原子和非原子屬性
  • 執行緒間通訊

NSThread建立和啟動執行緒

一個NSThread物件就代表一條執行緒

建立、啟動執行緒
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
// 執行緒一啟動,就會線上程thread中執行self的run方法

主執行緒相關用法
+ (NSThread *)mainThread; // 獲得主執行緒
- (BOOL)isMainThread; // 是否為主執行緒
+ (BOOL)isMainThread; // 是否為主執行緒

NSThread其他用法

獲得當前執行緒
NSThread *current = [NSThread currentThread];

執行緒的名字
- (void)setName:(NSString *)n;
- (NSString *)name;

其他建立執行緒方式

建立執行緒後自動啟動執行緒
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

隱式建立並啟動執行緒
[self performSelectorInBackground:@selector(run) withObject:nil];

上述2種建立執行緒方式的優缺點
優點:簡單快捷
缺點:無法對執行緒進行更詳細的設定

執行緒的狀態介紹

執行緒的狀態介紹

控制執行緒狀態

啟動執行緒
- (void)start; 
// 進入就緒狀態 -> 執行狀態。當執行緒任務執行完畢,自動進入死亡狀態

阻塞(暫停)執行緒
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 進入阻塞狀態

強制停止執行緒
+ (void)exit;
// 進入死亡狀態

`注意`:一旦執行緒停止(死亡)了,就不能再次開啟任務

多執行緒的安全隱患

  • 資源共享 1塊資源可能會被多個執行緒共享,也就是多個執行緒可能會訪問同一塊資源 比如多個執行緒訪問同一個物件、同一個變數、同一個檔案

  • 當多個執行緒訪問同一塊資源時,很容易引發資料錯亂和資料安全問題

  • 安全隱患示例01 – 存錢取錢 安全隱患示例01 – 存錢取錢

  • 安全隱患示例02 – 賣票 安全隱患示例02 – 賣票

  • 安全隱患分析 安全隱患分析

  • 安全隱患解決 – 互斥鎖 安全隱患解決 – 互斥鎖

    • 互斥鎖使用格式 @synchronized(鎖物件) { // 需要鎖定的程式碼 } 注意:鎖定1份程式碼只用1把鎖,用多把鎖是無效的

    • 互斥鎖的優缺點 優點:能有效防止因多執行緒搶奪資源造成的資料安全問題 缺點:需要消耗大量的CPU資源

    • 互斥鎖的使用前提:多條執行緒搶奪同一塊資源

    • 相關專業術語:執行緒同步 執行緒同步的意思是:多條執行緒在同一條線上執行(按順序地執行任務) 互斥鎖,就是使用了執行緒同步技術

原子和非原子屬性

  • OC在定義屬性時有nonatomic和atomic兩種選擇 atomic:原子屬性,為setter方法加鎖(預設就是atomic) nonatomic:非原子屬性,不會為setter方法加鎖

  • 原子和非原子屬性的選擇 nonatomic和atomic對比 atomic:執行緒安全,需要消耗大量的資源 nonatomic:非執行緒安全,適合記憶體小的移動裝置

  • iOS開發的建議 所有屬性都宣告為nonatomic 儘量避免多執行緒搶奪同一塊資源 儘量將加鎖、資源搶奪的業務邏輯交給伺服器端處理,減小移動客戶端的壓力

執行緒間通訊

  • 什麼叫做執行緒間通訊 在1個程序中,執行緒往往不是孤立存在的,多個執行緒之間需要經常進行通訊

  • 執行緒間通訊的體現 1個執行緒傳遞資料給另1個執行緒 在1個執行緒中執行完特定任務後,轉到另1個執行緒繼續執行任務

  • 執行緒間通訊常用方法 -(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; -(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

  • 執行緒間通訊示例 – 圖片下載執行緒間通訊示例 – 圖片下載

  • 執行緒間通訊方式 – 利用NSPort執行緒間通訊方式 – 利用NSPort