iOS多執行緒--NSThread

weixin_34290000發表於2017-09-01

一、NSThread簡介

每個NSThread物件對應一個執行緒,真正最原始的執行緒。
1)優點:NSThread 輕量級最低,相對簡單。
2)缺點:手動管理所有的執行緒活動,如生命週期、執行緒同步、睡眠等。

使用NSThread實現多執行緒的核心 (建立和控制)

核心1: 建立 ---- 三種建立、啟動執行緒的方式

方式一、動態例項化:

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(func) object:nil];
thread.threadPriority = 1;// 設定執行緒的優先順序(0.0 - 1.0,1.0最高階)
[thread start];
//執行緒啟動時,就會線上程thread中執行self中的func方法

方式二、靜態例項化:

//建立執行緒後自動啟動執行緒
[NSThread detachNewThreadSelector:(SEL) toTarget:(id) withObject:(id)];

方式三、隱式例項化:

//隱式建立並啟動執行緒
[self performSelectorInBackground:(SEL) withObject:(id)];

核心2: 控制 ---- NSThread的使用與操作控制

1.) 執行緒阻塞/延時:

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

2.) 執行緒死亡:

- (void)exit; // 強制退出執行緒

3.) 執行緒之間通訊:

//在指定執行緒上執行操作
[self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES]; 
//在主執行緒上執行操作
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES]; 
//在當前執行緒執行操作
[self performSelector:@selector(run) withObject:nil];

4.) 執行緒同步:(NSLock/鎖)
說到執行緒同步,就讓我們來舉一個經典的搶票的例子。搶票涉及到多個執行緒對同一個資料進行操作,NSThread是要自己管理執行緒同步的,讓同一個時間只有一個執行緒操作該資料,那麼我們就要用到加鎖

程式碼如下:ViewController.h

@interface ViewController ()
{
    NSInteger tickets;//剩餘票數
    NSInteger sellNum;//賣出票數
    NSThread* thread1;//買票執行緒1
    NSThread* thread2;//買票執行緒2
    NSLock* theLock;//鎖
}
@property (nonatomic, strong) NSThread* myThread;

@end

ViewController.m

//(執行緒同步)2人搶票  搶完為止
- (IBAction)clickOnBuyTickets:(id)sender {
    
    tickets = 7;
    sellNum = 0;
    theLock = [[NSLock alloc] init];
    
    thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(buyTickets) object:nil];
    [thread1 setName:@"Thread-1"];
    [thread1 start];
    
    
    thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(buyTickets) object:nil];
    [thread2 setName:@"Thread-2"];
    [thread2 start];
}

//買票
-(void)buyTickets {
    
    // 讓它一直把票售完跳出break為止
    while (TRUE) {
        //上鎖
        [theLock lock];
        if(tickets >= 0){
            [NSThread sleepForTimeInterval:0.09];
            sellNum = 7 - tickets;
            NSLog(@"當前票數是:%ld,售出:%ld,執行緒名:%@",tickets,sellNum,[[NSThread currentThread] name]);
            tickets--;
        }else{
            break;
        }
        [theLock unlock];
    }
}

上面的經典的搶票示例控制檯輸出資訊如下:

2017-09-01 13:51:58.978 Multi-thread_NSThread[52731:2272938] 當前票數是:7,售出:0,執行緒名:Thread-1
2017-09-01 13:51:59.068 Multi-thread_NSThread[52731:2272939] 當前票數是:6,售出:1,執行緒名:Thread-2
2017-09-01 13:51:59.164 Multi-thread_NSThread[52731:2272938] 當前票數是:5,售出:2,執行緒名:Thread-1
2017-09-01 13:51:59.259 Multi-thread_NSThread[52731:2272939] 當前票數是:4,售出:3,執行緒名:Thread-2
2017-09-01 13:51:59.353 Multi-thread_NSThread[52731:2272938] 當前票數是:3,售出:4,執行緒名:Thread-1
2017-09-01 13:51:59.448 Multi-thread_NSThread[52731:2272939] 當前票數是:2,售出:5,執行緒名:Thread-2
2017-09-01 13:51:59.541 Multi-thread_NSThread[52731:2272938] 當前票數是:1,售出:6,執行緒名:Thread-1
2017-09-01 13:51:59.634 Multi-thread_NSThread[52731:2272939] 當前票數是:0,售出:7,執行緒名:Thread-2

從上面我們可以看出:
加鎖來實現執行緒同步後,票是一張一張賣出去的。
那麼當把鎖去掉就會出現什麼樣的局面呢?
答案是:會出現兩個執行緒同時操作一個資料,最後出現了負數。有興趣的朋友可以試試!
好了,NSThread暫時就到這裡。後續有了更多有趣的我會再次完善;喜歡就關注我!上面的示例原始碼 在這裡

您可能還對 iOS多執行緒--GCD 感興趣
您可能還對 iOS多執行緒--NSOperation 感興趣

相關文章