多線程開發(fā)

關(guān)于多線程編程首先我們要了解清楚什么是線程,什么是進程,以及他們之間的區(qū)別和聯(lián)系。

所謂的線程就是CPU調(diào)度(執(zhí)行任務(wù))的最小單位,其實就是一段代碼。

而進程是CPU分配資源和調(diào)度的單位,說明白點就是系統(tǒng)中正在運行的一個應用程序。

兩者的聯(lián)系和區(qū)別

線程是進程的組成部分,一個進程可以開啟多個子線程,但是每一個進程至少需要有一個線程;

一個進程的所有任務(wù)都是在線程中執(zhí)行的

同一個進程內(nèi)的線程共享進程的資源

多線程的概念和原理

概念:一個程序開啟多條線程,每條線程可以并行(同時)執(zhí)行不同的任務(wù)

原理:(1)多個線程并發(fā)執(zhí)行,其本質(zhì)就是CPU快速地在多條線程之間切換。(2)當CPU調(diào)度線程的時間足夠快,就會造成多線程并發(fā)執(zhí)行的假象。

那么了解了這么多,我們學習多線程開發(fā)主要是為了什么呢?

簡單來說一下多線程的優(yōu)缺點

優(yōu)點:能適當?shù)靥岣叱绦虻膱?zhí)行效率,能適當提高資源利用率(CPU和內(nèi)存利用率)

缺點:創(chuàng)建多線程是有開銷的,包括內(nèi)存空間和創(chuàng)建時間上的開銷,如果開啟大量的線程,會導致程序性能降低,線程越多,CPU在調(diào)度線程上的開銷就越大

到底什么是主線程,以及他有什么作用,下面讓我們一起探索一下

定義:iOS程序運行后,默認開啟一條線程,稱為多線程

作用:顯示或刷新UI界面,處理UI事件

注意:不要將耗時操作放到主線程,耗時操作會卡死主線程,影響UI界面性能

實現(xiàn)多線程的方法主要有哪些?以及他們有哪些特點

NSThread:(偶爾OC)使用更加面向?qū)ο?簡單易用,可直接操作線程對象

GCD:(經(jīng)常C)旨在替代NSThread等線程技術(shù),充分利用設(shè)備的多核

NSOperation:(經(jīng)常OC)基于GCD,比GCD多了一些更簡單實用的功能,使用更加面向?qū)ο?/p>

項目中一般在哪用到多線程?

多線程一般用于耗時操作,如:網(wǎng)絡(luò)請求、上傳,下載文件、讀取數(shù)據(jù)庫、文件操作、大循環(huán)

什么是線程安全問題?有什么解決方案?

定義:多個線程同時訪問同一塊資源(例如同一個對象、變量、文件)時,引發(fā)的數(shù)據(jù)錯亂和數(shù)據(jù)安全問題,稱為線程安全問題

解決方法:1.添加互斥鎖;2.互斥鎖的使用格式 :@synchronized( 鎖對象 ){ //需要鎖定的代碼};3.加鎖的原理:使線程同步執(zhí)行

FMDB是線程安全的么?

FMDB如果使用FMDatabase類是線程不安全的

使用FMDatabaseQueue是線程安全的

線程通信的概念,如何實現(xiàn)?

概念:一個線程傳遞數(shù)據(jù)給另一個線程、一個線程中執(zhí)行完特定任務(wù)后,轉(zhuǎn)到另一個線程繼續(xù)執(zhí)行任務(wù)

實現(xiàn)方法:

performSelectorOnMainThread和performSelectorOnThread方法

performSelectorInBackground(后臺線程中執(zhí)行)

使用GCD的dispatch方法


GCD內(nèi)部怎么實現(xiàn)的,使用GCD有什么優(yōu)勢?

實現(xiàn)方式:

1.通過定制任務(wù)和將任務(wù)添加到隊列中來實現(xiàn)GCD的多線程功能

2.GCD會自動將隊列中的任務(wù)去出來,放到對應的線程中執(zhí)行

3.任務(wù)的取出遵循FIFO原則(先進先出)

優(yōu)勢:

1.會自動利用更多的CPU內(nèi)核

2.會自動管理線程的生命周期

全局并發(fā)隊列和使用create函數(shù)創(chuàng)建的并發(fā)隊列有什么區(qū)別?

1.全局并發(fā)隊列在整個程序中本身是默認存在的,并且對應有高優(yōu)先級,默認優(yōu)先級,低優(yōu)先級,后臺優(yōu)先級一共四種并發(fā)隊列,我們只是選擇其中一個來用,而使用create函數(shù)創(chuàng)建的并發(fā)隊列是實打?qū)嵉貜念^開始去創(chuàng)建一個隊列

2.iOS6之前,使用create函數(shù)創(chuàng)建的隊列都要進行一次Release,而全局并發(fā)隊列不需要我們手動Release。但在iOS6之后,GCD已經(jīng)納入ARC內(nèi)存操作中,不需要再進行Release

3.使用柵欄函數(shù)時,使用全局并發(fā)隊列是無效的,只有使用create創(chuàng)建的并發(fā)隊列才有效(特別需要注意)

GCD中如何控制多線程并發(fā)執(zhí)行時的執(zhí)行順序

使用柵欄函數(shù)dispatch_barrier_async

GCD除了開線程,還可以用在什么地方?

1.單例:一次函數(shù)dispatch_once

2.延遲函數(shù):dispatch_after,可以定義執(zhí)行任務(wù)的線程

3.定時器:dispatch_source_set_event_handler

4.快速迭代:dispatch_apply

GCD快速迭代的定義和作用?

定義:同時開啟主線程和子線程并發(fā)完成循環(huán)操作

作用:大大提高循環(huán)操作的效率

GCD中隊列組的作用

使用隊列組,除了可以開啟新的線程,同時還能通過group監(jiān)聽隊列中任務(wù)的執(zhí)行情況

如何處理GCD造成的死鎖問題

1.將隊列改為非主隊列

2.將調(diào)度方式改為異步調(diào)度

NSOperation和GCD的區(qū)別?

1.實現(xiàn)機制的區(qū)別:

(1).使用這兩者執(zhí)行任務(wù)都會由系統(tǒng)自動創(chuàng)建、銷毀子線程

(2).GCD底層是基于C語言的,NSOperation則是對GCD的封裝,是面向?qū)ο蟮?/p>

(3).NSOperation只有兩種類型的隊列,主隊列和非主隊列(非主隊列既可以是并行的也可以是串行的,默認是并行的)

(4).GCD擁有四種類型的隊列 (main, global, create[serial], create[concurrent] )

2.使用上的區(qū)別:

(1).GCD的使用更輕量級,而NSOperation作為對象提供了更豐富的API

(2).在NSOperationQueue中,可以隨時取消要準備執(zhí)行的任務(wù),而GCD沒法停止已經(jīng)加入queue的block中的任務(wù)

(3).KVO能應用在NSOperation中,以監(jiān)聽一個Operation是否完成或取消,這樣能比GCD更加有效地掌控我們執(zhí)行的后臺任務(wù)

(4).NSOperation通過繼承,可以提高代碼的復用度,這比GCD更有自由度和擴展性

(5).同一個并行隊列中的任務(wù)執(zhí)行時,我們能夠設(shè)置NSOperation的priority(優(yōu)先級),使之按順序執(zhí)行,而在GCD中,要使block中的任務(wù)實現(xiàn)這個功能,需要大量復雜代碼

什么是最大任務(wù)并發(fā)數(shù)?NSOperationQueue中如何操縱隊列中的任務(wù)?

線程的最大任務(wù)并發(fā)數(shù):異步執(zhí)行時同一時間內(nèi)可以同時執(zhí)行的操作的最大數(shù)

當maxConcurrentOperationCount = 1,只能執(zhí)行一個操作,隊列為串行隊列

當maxConcurrentOperationCount = 0,無法執(zhí)行任何操作

當maxConcurrentOperationCount > 1,隊列為并發(fā)隊列

默認條件下maxConcurrentOperationCount = -1,代表最大并發(fā)數(shù)沒有限制

NSOperationQueue處理A,B,C三個線程,要求執(zhí)行完A,B后才能執(zhí)行C,怎么做?

添加依賴關(guān)系,AB都依賴C

- (void)operation{

NSOperationQueue*queue = [[NSOperationQueuealloc] init];

NSBlockOperation*opA = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"A----%@",[NSThreadcurrentThread]);?

?}];

NSBlockOperation*opB = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"B----%@",[NSThreadcurrentThread]);

?}];

NSBlockOperation*opC = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"C----%@",[NSThreadcurrentThread]);

?}];

//注意:不能互相依賴

[opC addDependency:opA];

?[opC addDependency:opB];

?[queue addOperation:opA];?

?[queue addOperation:opB];

?[queue addOperation:opC];

NSLog(@"----end----");

}

有一個需求,需要將N個請求全部完成之后執(zhí)行某個操作,該如何處理

1.GCD中可以使用柵欄函數(shù)或者隊列組

2.NSOperation中可以添加依賴關(guān)系

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容