iOS開發 - 多線程

來源:互聯網
上載者:User

iOS開發 - 多線程

知識點
1.理解線程的概念
2.NSThread的使用
3.NSOperation的使用
4.GCD的使用
5.線程鎖,安全執行緒

===============================
1.多線程是一種實現多任務並發執行的技術,允許同時執行多個任務,能夠更合理的利用CPU的資源,提高效率、防止使用者介面卡頓。
在iOS中,所有的UI處理只能在主線程做。

什麼是進程?
· 簡單的說進程就是我們電腦上啟動並執行一個個應用程式,每一個程式就是一個進程,並且每個進程之間是獨立的,每個進程運行在其專用受保護的記憶體空間內(window系統可以通過工作管理員進行查看,Mac系統中可以通過活動監視器對其進行查看)
什麼是線程?
· 通過上面的介紹我們知道了什麼是進程,那麼如何讓進程運行起來,這個時候就要有線程了,也就是說每個應用程式想要跑起來,最少也要有一條線程存在,其實應用程式啟動的時候我們的系統就會預設幫我們的應用程式開啟一條線程,這條線程也叫做’主線程’,或者’UI線程’
進程和線程之間的關係
· 線程是進行的執行單元,進程的所有任務都線上程中執行,舉例來說:進程就好比公司中的一個個部門,線程則代表著部門中的同事,而主線程當然是我們的老闆了,一個公司部能沒有老闆,一個程式不能沒有線程其實都是一個道理.
什麼是CPU?
· CPU(中央處理器,Central Processing Unit)是一塊超大規模的整合電路,只要用來解釋電腦指令以及處理電腦軟體中的資料.
多線程的原理
· 同一時間,CPU值能處理一個線程,只有一條線程在執行,多線程指的就是多條線程同時執行,其實就是CPU快速的在多條線程之間的切換,如果CPU調度線程的時間足夠快,那麼就會造成多線程並發執行的假象,而當線程特別多的時候,那麼CPU在多條切換的效率也就會下降,同時消耗大量的CPU資源,線程的執行效率也就會下降.
多線程優點
· 能適當提高程式的執行效率
· 能適當提高資源的利用率
多線程的缺點
· 開啟線程需要佔用一定的記憶體空間,如果開啟大量的線程,則會佔用大量的記憶體空間,降低程式的效能
· 線程越多,CPU在調度線程上得開銷就越大,程式的設計上也就更加的複雜,因此不推薦開啟太多的線程,一般開啟2~5條為最佳(且用且珍惜);
主線程
· 也就是應用程式啟動的時候,系統預設幫我們建立的線程,稱之為’主線程’或者是’UI線程’;
· 主線程的作用一般都是用來顯示或者重新整理UI介面例如:點擊,滾動,拖拽等事件

===============================
2.NSThread線程式控制制
1).建立線程,並自動執行
[NSThread detachNewThreadSelector:@selector(doSomeThing) toTarget:self withObject:nil];

2).建立線程,不自動執行    [[NSThread alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];3).設定線程名    thread.name = @"另一個線程";4).執行線程    [thread start];5).線程取消    [thread cancel];6).函數內擷取當前線程    [NSThread currentThread];7).擷取主線程    [NSThread mainThread];7).線程休眠    [NSThread sleepForTimeInterval:1.0f];  // 休眠幾秒    [NSThread sleepUntilDate:date]; // 休眠到指定時間8).線程退出    [NSThread exit];9).線程通訊    [self performSelector:@selector(function) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];

===============================
3.NSOperation,是以任務為中心的一種多線程技術,並不直接管理線程
1).NSOperation是抽象父類,不要直接使用,而應該使用它的子類
NSInvocationOperation
[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];

    NSBlockOperation        [NSBlockOperation blockOperationWithBlock:^{}];    新增工作間的依賴關係,前者依賴於後者的完成,也就是後者執行完,前者才能執行,依賴關係需要放在添加到隊列之前設定        [invocation addDependency:blockOperation];    如果有必要,可以讓Operation取消         [invocation cancel];2.NSOperationQueue,任務隊列,NSOperation對象需要添加到隊列裡面才會執行    添加到隊列裡之後,自動會給每個NSOperation對象建立一個線程去執行    建立NSOperationQueue        [[NSOperationQueue alloc] init];    設定最大並發數        queue.maxConcurrentOperationCount = 1;    新增工作到隊列裡        [queue addOperation:blockOperation];    讓隊列裡面,所有的Operation都取消        [queue cancelAllOperations];    擷取當前線程對列        currentQueue    擷取主線程對列        mainQueue

===============================
4.GCD是一套C語言的線程式控制制API,是NSOperation的底層實現,用Block來表示一個任務
1).建立隊列
dispatch_queue_create(“QF Queue”, DISPATCH_QUEUE_CONCURRENT);

2).系統的隊列    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //  全域隊列    dispatch_get_main_queue();    //  主線程隊列3).非同步執行任務    dispatch_async(globalQuque, ^{});4).建立分組    dispatch_group_create();5).新增工作到分組,並執行    dispatch_group_async(group, globalQuque, ^{});6).分組執行完的通知    dispatch_group_notify(group, mainQuque, ^{});

===============================
5.線程鎖
1).方式1:
_lock = [[NSLock alloc] init];

[_lock tryLock];[_lock unlock];2).方式2:   @synchronized(self) {}

NSThread

//多線程 -- 為了將一些耗時的操作放在多線程中去執行 主要是為了給一個好的使用者體驗,防止卡頓的效果//越多越好? 消耗記憶體和cpu的使用效率//建立多線程的方式//1.NSThread//2.CGD//3.NSOperation//程式啟動並執行時候,會預設建立一個線程,這個線程稱之為主線程/UI線程,所有的UI相關的操作都需要在這個線程中執行BOOL res1 = [NSThread isMainThread]; //判斷是否是子線程BOOL RES2 = [NSThread isMultiThreaded]; //判斷是否是多線程

//1.建立線程 減方法建立
//操作 – 功能 – 若干行代碼 – 函數 – 任務
NSThread * thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(threadRun) object:nil];
//第三個參數: object 如果第二個參數selector帶參的話 就使用object傳遞
//新建立的線程稱之為子線程或者任務線程/後台線程

//線程的名字thread1.name = @"子線程1";//線程的優先順序(double) 0 - 1thread1.threadPriority = 0.5;//設定線程的優先順序(枚舉值)需要線上程開啟前設定 否則無效。thread1.qualityOfService = NSQualityOfServiceBackground;//2.開啟線程[thread1 start];

//建立線程 加方法建立並且執行線程
[NSThread detachNewThreadSelector:@selector(threadRun) toTarget:self withObject:nil];
//設定不了線程的名字 可以到方法裡通過currentThread方法拿到線程 再進行賦值操作

//NSObject方法 建立線程
[self performSelectorInBackground:@selector(threadRun) withObject:nil];

GCD
//GCD - 基於C語言的一套API介面,它是把Block作為任務,添加到隊列中進行操作

//GCD 優點:可以控制多個線程的執行順序 這個功能是NSThread不具有的 //缺點: 不能取消線程//GCD 文法都是c語言函數//1.建立隊列dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);//queue 隊列/線程池//dispatch 調度/執行//第一個參數 隊列的名字 通常寫nil//第二個參數 串列/並行//DISPATCH_QUEUE_SERIAL 串列  按順序執行隊列裡的線程//DISPATCH_QUEUE_CONCURRENT 並行  同時執行若干個線程

監聽線程的退出

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadOut) name:NSThreadWillExitNotification object:nil];//NSThreadWillExitNotification 線程退出的頻道//只需要監聽這個頻道 當線程退出的時候 就會收到通知/訊息 然後調用響應的方法//取消線程 cancel並不能把一個線程退出 調用cancle方法只是為了告訴當前線程的isCancelled屬性為YES 並且觸發監聽[thread cancel];if (thread.isCancelled) {    //如果為YES 退出線程 也可以使用return    [NSThread exit];}//threadRun這個方法是我們子線程的入口函數 - 當這個方法執行完畢的時候,線程就已經是死亡狀態了

定時器

//GCD定時器//1.建立定時器//需要把定時器定義成全域變數 否則會被立刻釋放self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());//2.設定定時器 第一個參數為時間間隔 第二個參數次數dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);//3.定時器定時的操作dispatch_source_set_event_handler(self.timer, ^{    //定時器每隔幾秒鐘要做的操作    NSLog(@"d");});//執行定時器dispatch_resume(self.timer);

延時操作

[NSThread sleepForTimeInterval:2.0];[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];-(void)createQueue2{    NSLog(@"將要延時...");    //延時幾秒操作    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        //DISPATCH_TIME_NOW 從現在開始        //NSEC_PER_SEC 代表的是秒         //延時幾秒之後的操作        NSLog(@"延時執行");    });    [self performSelector:@selector(afterRun) withObject:nil afterDelay:2.0];    [NSObject cancelPreviousPerformRequestsWithTarget:self];}

線程組

//線程組  監聽線程dispatch_group_t group = dispatch_group_create();//建立全域隊列dispatch_queue_t queue = dispatch_get_global_queue(0, 0);dispatch_group_async(group, queue, ^{    [NSThread sleepForTimeInterval:2.0];    NSLog(@"線程1執行完畢");});dispatch_group_async(group, queue, ^{    [NSThread sleepForTimeInterval:3.0];    NSLog(@"線程2執行完畢");});//前兩個線程結束後會通知這個線程dispatch_group_notify(group, dispatch_get_main_queue(), ^{    NSLog(@"返回主線程");});

阻塞線程組

dispatch_group_t group = dispatch_group_create();//非同步作業組dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{    for (int i = 0; i < 5; i ++) {        //進入線程組        dispatch_group_enter(group);        [NSThread sleepForTimeInterval:1.f];        NSLog(@"線程 --- %d",i);        //離開線程組        dispatch_group_leave(group);    }});//目的:先執行完前面的線程 再執行後面的線程//阻塞線程組dispatch_group_wait(group, DISPATCH_TIME_FOREVER);//非同步作業隊列dispatch_async(dispatch_get_global_queue(0, 0), ^{    NSLog(@"另一個線程執行了");});
pragma mark - 重複

-(void)createQueue1{
//重複執行某個線程
//第一個參數 重複執行的次數
dispatch_apply(5, dispatch_get_global_queue(0, 0), ^(size_t idx) {
NSLog(@”線程執行…”);
});
}

pragma mark - 柵欄

-(void)createQueue2{

dispatch_queue_t queue = dispatch_get_global_queue(0,0);dispatch_async(queue, ^{    NSLog(@"線程1");});dispatch_async(queue, ^{    NSLog(@"線程2");});dispatch_barrier_async(queue, ^{    NSLog(@"barrier...");});dispatch_async(queue, ^{    NSLog(@"線程3");});

}

pragma mark - 訊號量

-(void)createQueue3{

//訊號量//建立訊號量 參數為計數dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);dispatch_async(dispatch_get_global_queue(0, 0), ^{    //等待接收訊號 接收訊號要寫在當前線程所有操作之前 計數-1    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);    NSLog(@"線程1執行...");});dispatch_async(dispatch_get_global_queue(0, 0), ^{    NSLog(@"線程2執行...");     //發送訊號 在當前線程操作執行完畢之後 再發送訊號  計數+1    dispatch_semaphore_signal(semaphore);});dispatch_async(dispatch_get_global_queue(0, 0), ^{            NSLog(@"線程3執行...");});dispatch_async(dispatch_get_global_queue(0, 0), ^{    NSLog(@"線程4執行...");});

}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.