天天看點

iOS NSThread和線程鎖一、NSThread 多線程的優缺點:二、NSThread的使用:三、NSThread的屬性四、擷取目前線程五、擷取主線程六、暫停目前線程七、線程間的通信八、線程同步

一、NSThread 多線程的優缺點:

  • 優點:NSThread比NSOperation和GCD輕量級;
  • 缺點:需要自己管理線程的生命周期,線程同步。線程同步對資料的加鎖會有一定的系統開銷。

二、NSThread的使用:

1、NSThread有兩種直接建立方式:

  • ①、- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument ;
  • ②、+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

例如:

// 這種建立線程⾃自動就運⾏行

(1)、動态建立

NSThread *t2 = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain2:) object:nil];
// 設定線程的優先級(0.0 - 1.0,1.0最進階)
t2.threadPriority = 1;
[t2 start];
           

(2)、靜态建立

[NSThread detachNewThreadSelector:@selector(threadMain0:) toTarget:self withObject:@"111"];
- (void)threadMain0:(NSString *)obj{
    NSLog(@"obj = %@",obj); //111
}
           

2、參數的意思

  • ①、selector:線程執行的方法,這個selector隻能有一個參數,而且不能有傳回值;
  • ②、target:selector消息發送對象;
  • ③、object:傳輸給target的唯一參數,也可以為nil。
    第一種方式會直接建立線程并且開始運作線程,第二種方式是先建立線程對象,然後再運作線程操作,在運作線程操作前可以設定線程的優先級等線程資訊。
               

3、隐藏式建立

[self performSelectorInBackground:@selector(threadMain3:) withObject:@"333”];
           

三、NSThread的屬性

NSThread* current = [NSThread currentThread];
           

1、傳回目前線程

+ (NSThread *)currentThread;
           

2、判斷是否為多線程

+ (BOOL)isMultiThreaded;
           

3、暫停

+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
           

4、退出線程

+ (void)exit;
           

5、設定線程的優先級(0.0,-1.0,1.0最高)

+ (double)threadPriority;
+ (BOOL)setThreadPriority:(double)p;
           

6、線程函數位址

+ (NSArray *)callStackReturnAddresses;
           

7、設定與傳回線程名稱 設定與傳回線程名稱

@property (copy) NSString *name;
           

8、線程堆棧

@property NSUInteger stackSize;
           

9、 判斷目前線程是否為主線程

+ (BOOL)isMainThread NS_AVAILABLE(10_5, 2_0);
+ (NSThread *)mainThread NS_AVAILABLE(10_5, 2_0);
           

10、是否在執行

@property (readonly, getter=isExecuting) BOOL executing;
           

11、是否已經結束

@property (readonly, getter=isFinished) BOOL finished;
           

12、是否取消的

@property (readonly, getter=isCancelled) BOOL cancelled;
           

13、取消操作

- (void)cancel NS_AVAILABLE(10_5, 2_0);
           

14、線程啟動

- (void)start NS_AVAILABLE(10_5, 2_0);
           

四、擷取目前線程

NSThread* current = [NSThread currentThread];
           

五、擷取主線程

NSThread* current = [NSThread mainThread];
           

六、暫停目前線程

1、暫停

[NSThread sleepForTimeInterval:2];
           

2、暫停

NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:date]
           

七、線程間的通信

注意:線程入口函數一旦調用完成後該線程就結束了。

1、在指定線程上執行操作

[self performSelector:@selector(run) onThread:_myThread withObject:nil waitUntilDone:YES];
           

2、在主線程執行操作

[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
           

3、在目前線程執行操作

[self performSelector:@selector(run) withObject:nil];
           

八、線程同步

1、NSLock

加鎖:

  • ①、- (BOOL)tryLock;
  • ②、- (void)lock;
  • ③、- (BOOL)lockBeforeDate:(NSDate *)limit;

解鎖:

  • ①、- (void)unlock;

2、synchornized代替NSLock

@synchronized(self)
{
    // Everything between the braces is protected by the @synchronized directive.
}
           

@synchronized,代表這個方法加鎖, 相當于不管哪一個線程(例如線程A),運作到這個方法時,都要檢查有沒有其它線程例如B正在用這個方法,有的話要等正在使用synchronized方法的線程B運作完這個方法後再運作此線程A,沒有的話,直接運作。它包括兩種用法:synchronized 方法和 synchronized 塊。

@synchronized 方法控制對類(一般在IOS中用在單例中)的通路:每個類執行個體對應一把鎖,每個 synchronized 方法都必須獲得調用該方法鎖方能執行,否則所屬就會發生線程阻塞,方法一旦執行,就獨占該鎖,直到從該方法傳回時才将鎖釋放,此後被阻塞的線程方能獲得該鎖,重新進入可執行狀态。這種機制確定了同一時刻對于每一個類,至多隻有一個處于可執行狀态,進而有效避免了類成員變量的通路沖突(隻要所有可能通路類的方法均被聲明為 synchronized)。

synchronized 塊:

@通過 synchronized關鍵字來聲明synchronized 塊。文法如下:

@synchronized(syncObject) { }

synchronized 塊是這樣一個代碼塊,其中的代碼必須獲得對象 syncObject (如前所述,可以是類執行個體或類)的鎖方能執行,具體機制同前所述。由于可以針對任意代碼塊,且可任意指定上鎖的對象,故靈活性較高。

3、NSCondition

NSCodition是一種特殊類型的鎖,我們可以用它來同步操作執行的順序。等待某個NSCondition的線程一直被lock,知道其他線程給那個condition發送了信号。

例如:

- (void)run{
    while (TRUE) {
        // 上鎖
        [ticketsCondition lock];
        [ticketsCondition wait];
        //操作
        [ticketsCondition unlock];
    }
}
//其他線程發送信号通知上面的線程,就可以運作了
-(void)run2{
    while (YES) {
        [ticketsCondition lock];
        [NSThread sleepForTimeInterval:3];
        [ticketsCondition signal];
        [ticketsCondition unlock];
    }
}
           

4、循環鎖:NSRecursiveLock

5、條件鎖:NSConditionLock

6、分布式鎖:NSDistributedLock

繼續閱讀