版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
多線程講師:劉凡技術(shù)博客:/liufan9多線程的應(yīng)用應(yīng)用中的網(wǎng)絡(luò)圖片、視頻、歌曲、書籍等資源下載游戲中的聲音播放多線程示意圖充分發(fā)揮多核處理器的優(yōu)勢,并發(fā)執(zhí)行任務(wù)讓系統(tǒng)運行的更快、更流暢任務(wù)2任務(wù)…任務(wù)N任務(wù)1并發(fā)任務(wù)2任務(wù)2任務(wù)(…)任務(wù)N任務(wù)1并發(fā)任務(wù)1單線程示意圖多線程示意圖“執(zhí)行流”的概念單核雙核進程與線程概念一個運行的程序就是一個進程或者叫做一個任務(wù)一個進程至少包含一個線程,線程是程序的執(zhí)行流iOS程序啟動時,在創(chuàng)建一個進程的同時,會開始運行一個線程,該線程被稱為主線程主線程是其他線程最終的父線程,所有界面的顯示操作必須在主線程進行!??!系統(tǒng)中的每一個進程都有自己獨立的虛擬內(nèi)存空間,而同一個進程中的多個線程則共用進程的內(nèi)存空間每創(chuàng)建一個新的線程,都會消耗一定內(nèi)存和CPU時間當多個線程對同一個資源出現(xiàn)爭奪的時候需要注意線程安全問題多線程的優(yōu)勢與難點優(yōu)勢充分發(fā)揮多核處理器優(yōu)勢,將不同線程任務(wù)分配給不同的處理器,真正進入“并行運算”狀態(tài)將耗時、輪詢或者并發(fā)需求高等任務(wù)分配到其他線程執(zhí)行,并由主線程負責統(tǒng)一更新界面會使得應(yīng)用程序更加流暢,用戶體驗更好當硬件處理器的數(shù)量增加,程序會運行更快,而無需做任何調(diào)整難點共享資源的“爭奪”多線程是為了同步完成多項任務(wù),不是為了提高運行效率,而是為了通過提高資源使用效率來提高系統(tǒng)的整體性能多線程使用注意事項線程使用不是無節(jié)制的iOS中的主線程的堆棧大小是1M從第二個線程開始都是512KB這些數(shù)值不能通過編譯器開關(guān)或線程API函數(shù)更改只有主線程有直接修改UI的能力iOS的三種多線程技術(shù)NSThreadNSOperationGCD——GrandCentralDispatch,是基于C語言的框架以上這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。但是就目前而言,iOS的開發(fā)者,需要了解三種多線程技術(shù)的基本使用過程。因為很多框架技術(shù)分別使用了不同多線程技術(shù)。例如NSURLConnection的異步靜態(tài)方法:sendAsynchronousRequest:requestqueue:[NSOperationQueuemainQueue]
completionHandler:^(NSURLResponse*response,NSData*data,NSError*error)三種多線程技術(shù)的對比NSThread:優(yōu)點:NSThread比其他兩個輕量級,使用簡單缺點:需要自己管理線程的生命周期、線程同步。線程同步對數(shù)據(jù)的加鎖會有一定的系統(tǒng)開銷NSOperation:不需要關(guān)心線程管理,數(shù)據(jù)同步的事情,可以把精力放在自己需要執(zhí)行的操作上GCD:GrandCentralDispatch是由蘋果開發(fā)的一個多核編程的解決方案。iOS4.0+才能使用,是替代NSThread,NSOperation的高效和強大的技術(shù)多線程演練——賣票系統(tǒng)預(yù)設(shè)共有100張票可以銷售(開發(fā)時可以少一些,專注實現(xiàn))售票工作由兩個線程并發(fā)進行沒有可出售票據(jù)時,線程工作停止兩個線程的執(zhí)行時間不同,模擬售票人員效率不同使用一個多行文本框公告售票進度(主線程更新UI)線程工作安排主線程:負責更新UI線程1:模擬第1名賣票員線程2:模擬第2名賣票員兩個線程幾乎同時開始賣票單線程賣票流程圖是否還有票?顯示當前票數(shù)總票數(shù)-1模擬售票其他耗時操作賣票結(jié)束YesNo多線程賣票示意圖共享資源(票)賣票線程1賣票線程2賣票流程賣票流程演練準備——更新UI方法,由主線程調(diào)用//向文本框追加文本-(void)appendTextView:(NSString*)text{
NSMutableString*str=[NSMutableString
stringWithString:[_infoTextView
text]];[strappendFormat:@"\n%@",text];
NSRangerange=NSMakeRange(str.length,1);[_infoTextView
setText:str];
//滾動至文本框文字末尾[_infoTextView
scrollRangeToVisible:range];}NSThread創(chuàng)建線程方法:+(void)detachNewThreadSelector:(SEL)selectortoTarget:(id)targetwithObject:(id)argument;-(id)initWithTarget:(id)targetselector:(SEL)selectorobject:(id)argument;參數(shù)說明:selector:線程執(zhí)行的方法,只能有一個參數(shù),不能有返回值target:selector消息發(fā)送的對象argument:傳輸給target的唯一參數(shù),也可以是nilNSObject直接加入了多線程的支持,允許對象的某個方法在后臺運行(本方法普遍應(yīng)用在游戲中,利用多線程播放聲音)-(void)performSelectorInBackground:(SEL)aSelectorwithObject:(id)arg;NSThread使用流程創(chuàng)建線程啟動線程線程執(zhí)行的方法——對應(yīng)前文單線程賣票流程圖while(YES){
if(_tickets>0){
NSString*str=[NSString
stringWithFormat:@"當前票數(shù):%d,售票線程:%@",_tickets,[[NSThreadcurrentThread]name]];
//調(diào)用主線程方法更新UI[self
performSelectorOnMainThread:@selector(appendTextView:)withObject:strwaitUntilDone:YES];
_tickets--;
//模擬休息
if([[[NSThread
currentThread]name]isEqualToString:@"售票線程-1"]){[NSThread
sleepForTimeInterval:0.3f];}else{[NSThread
sleepForTimeInterval:0.2f];}}else{
NSString*str=[NSString
stringWithFormat:@"票已售完,售票線程:%@",[[NSThreadcurrentThread]name]];
//調(diào)用主線程方法更新UI[self
performSelectorOnMainThread:@selector(appendTextView:)withObject:strwaitUntilDone:YES];
break;}}NSThread售票方法//設(shè)置預(yù)售票數(shù),共享資源!_tickets=20;//創(chuàng)建線程1NSThread*thread1=[[NSThread
alloc]initWithTarget:self
selector:@selector(threadSaleMethod)object:nil];//設(shè)置線程名稱,因為需要通過線程名稱跟蹤線程執(zhí)行情況,因此此處不使用線程靜態(tài)方法[thread1setName:@"售票線程-1"];//啟動線程1[thread1start];//創(chuàng)建線程2,步驟同上NSThread*thread2=[[NSThread
alloc]initWithTarget:self
selector:@selector(threadSaleMethod)object:nil];[thread2setName:@"售票線程-2"];[thread2start];運行,資源爭奪!解決方案:使用共享資源時——加鎖!加鎖方案1——對單個售票流程加鎖while(YES){
//加鎖
[_threadLocklock];
if(_tickets>0){//……
if([[[NSThread
currentThread]name]isEqualToString:@"售票線程-1"]){[NSThread
sleepForTimeInterval:1.0f];}else{[NSThread
sleepForTimeInterval:0.1f];}}else{//……
//解鎖[_threadLock
unlock];
break;}
//解鎖
[_threadLockunlock];}數(shù)據(jù)安全了,線程休眠模擬卻無法體現(xiàn)了!加鎖方案2——在共享資源被爭奪范圍內(nèi)加鎖//加鎖[_threadLocklock];if(_tickets>0){
NSString*str=[NSString
stringWithFormat:@"當前票數(shù):%d,售票線程:%@",_tickets,[[NSThreadcurrentThread]name]];
//調(diào)用主線程方法更新UI[self
performSelectorOnMainThread:@selector(appendTextView:)withObject:strwaitUntilDone:YES];//盡早地使用完共享資源,然后解鎖
_tickets--;
//解鎖[_threadLockunlock];
//……加鎖易犯的錯誤——只對部分共享資源加鎖if(_tickets>0){
NSString*str=[NSString
stringWithFormat:@"當前票數(shù):%d,售票線程:%@",_tickets,[[NSThreadcurrentThread]name]];
//調(diào)用主線程方法更新UI[self
performSelectorOnMainThread:@selector(appendTextView:)withObject:strwaitUntilDone:YES];
//加鎖[_threadLocklock];_tickets--;
//解鎖[_threadLockunlock];NSThread使用小結(jié)當涉及到共享資源爭奪時,共享資源的數(shù)據(jù)加鎖是一個難點,既要保證數(shù)據(jù)安全,又要保證線程執(zhí)行效率使用前加鎖盡快使用使用完解鎖再去做其他的事情多線程編寫順序單個方法調(diào)試OK單個線程調(diào)試OK增加線程,并考慮線程加鎖、解鎖的準確位置。注意:只有主線程能夠修改UI如果不涉及到內(nèi)存爭搶,NSThread寫多線程是最簡單的當不涉及共享資源爭奪時,使用NSObject的performSelectorInBackground方法可以非常的方便地實現(xiàn)多線程定義一個鎖加鎖解鎖線程1包括內(nèi)存加鎖解鎖線程2包括內(nèi)存加鎖NSOperation
&
NSOperationQueueNSOperation的兩個子類NSInvocationOperationNSBlockOperation工作原理:用NSOperation封裝要執(zhí)行的操作將創(chuàng)建好的NSOperation對象放NSOperationQueue中啟動OperationQueue開始新的線程執(zhí)行隊列中的操作注意事項:使用多線程時通常需要控制線程的并發(fā)數(shù),因為線程會消耗系統(tǒng)資源,同時運行的線程過多,系統(tǒng)會變慢使用以下方法可以控制并發(fā)的線程數(shù)量:-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;NSOperation操作流程定義操作1
~
N定義隊列將操作添加至隊列隊列是自動啟動的OperationQueue調(diào)度的方法while(YES){
if(_tickets>0){
//在主線程操作隊列更新界面[[NSOperationQueue
mainQueue]addOperationWithBlock:^{
NSString*str=[NSString
stringWithFormat:@"當前票數(shù):%d,售票線程:%@",_tickets,operationName];[self
appendTextView:str];
_tickets--;}];
//模擬休息
//……
}else{
//在主線程操作隊列更新界面[[NSOperationQueue
mainQueue]addOperationWithBlock:^{
NSString*str=[NSString
stringWithFormat:@"票已售完,售票線程:%@",operationName];[self
appendTextView:str];}];
break;}}NSInvocationOperation售票方法//設(shè)置預(yù)售票數(shù),共享資源!_tickets=20;//定義操作1NSInvocationOperation*operation1=[[NSInvocationOperation
alloc]initWithTarget:self
selector:@selector(operationSaleMethod:)object:@"售票操作-1"];//定義操作2NSInvocationOperation*operation2=[[NSInvocationOperation
alloc]initWithTarget:self
selector:@selector(operationSaleMethod:)object:@"售票操作-2"];//定義操作隊列NSOperationQueue*queue=[[NSOperationQueue
alloc]init];[queueaddOperation:operation1];[queueaddOperation:operation2];NSBlockOperation售票方法(需要補錄視頻)//設(shè)置預(yù)售票數(shù),共享資源!_tickets=20;//定義操作隊列NSOperationQueue*queue=[[NSOperationQueue
alloc]init];[queueaddOperationWithBlock:^{[self
operationSaleMethod:@"售票操作-1"];}];[queueaddOperationWithBlock:^{[self
operationSaleMethod:@"售票操作-2"];}];測試限制線程并發(fā)數(shù)量——體會執(zhí)行流的概念//設(shè)置預(yù)售票數(shù),共享資源!_tickets=20;//定義操作隊列NSOperationQueue*queue=[[NSOperationQueue
alloc]init];[queueaddOperationWithBlock:^{[self
operationSaleMethod:@"售票操作-1"];}];[queueaddOperationWithBlock:^{[self
operationSaleMethod:@"售票操作-2"];}];[queueaddOperationWithBlock:^{[self
operationSaleMethod:@"售票操作-3"];}];//設(shè)置最大線程數(shù)量[queuesetMaxConcurrentOperationCount:2];NSOperation使用小結(jié)NSOperation中無需使用線程鎖除更新UI之外,對共享資源的爭奪也需放在主線程隊列之中將定義的操作添加至隊列之后,多線程便開始啟動NSBlockOperation的使用相比NSInvocationOperation更加靈活、方便通過setMaxConcurrentOperationCount方法可以控制并發(fā)的最大線程數(shù)量GCDGCD是基于C語言的框架工作原理:讓程序平行排隊的特定任務(wù),根據(jù)可用的處理資源,安排它們在任何可用的處理器上執(zhí)行任務(wù)要執(zhí)行的任務(wù)可以是一個函數(shù)或者一個block底層是通過線程實現(xiàn)的,不過程序員可以不必關(guān)注實現(xiàn)的細節(jié)GCD中的FIFO隊列稱為dispatchqueue,可以保證先進來的任務(wù)先得到執(zhí)行dispatch_
_notify可以實現(xiàn)監(jiān)聽一組任務(wù)是否完成,完成后得到通知dispatchqueue:Maindispatchqueue:是全局可用的隊列,用于在主線程上執(zhí)行任務(wù)Serial:同時只執(zhí)行一個任務(wù)Concurrent:可以并發(fā)地執(zhí)行多個任務(wù),但是執(zhí)行完成的順序是隨機的GCD使用流程1.獲取全局調(diào)度隊列2.創(chuàng)建調(diào)度群組3.向調(diào)度群組添加異步任務(wù),并指定執(zhí)行隊列4.接收群組調(diào)度完成通知,群組中所有任務(wù)完成后獲得通知GCD調(diào)度的方法while(YES){
if(_tickets>0){
//在主調(diào)度隊列更新界面
dispatch_async(dispatch_get_main_queue(),^{
NSString*str=[NSString
stringWithFormat:@"當前票數(shù):%d,售票線程:%@",_tickets,gcdName];[self
appendTextView:str];
_tickets--;});
//模擬休息
if([gcdNameisEqualToString:@"售票GCD-1"]){[NSThread
sleepForTimeInterval:0.1f];}else{[NSThread
sleepForTimeInterval:0.2f];}}else{
break;}}GCD售票方法//設(shè)置預(yù)售票數(shù),共享資源!_tickets=20;//1.獲取默認調(diào)度優(yōu)先級的全局調(diào)度隊列,第二個參數(shù)為今后拓展使用,目前始終
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024版指標房屋銷售協(xié)議條款版
- 二手房交易中介協(xié)議合同范本(2024版)
- 2025年度銷售業(yè)務(wù)員兼職崗位員工激勵與績效改進合同2篇
- 二零二五年度別墅景觀綠化養(yǎng)護合同3篇
- 二零二五版國際會展中心物業(yè)全面服務(wù)與管理協(xié)議3篇
- 專業(yè)廣告代理服務(wù)協(xié)議(2024版)版A版
- 2024項目合作中間人傭金協(xié)議書
- 二零二五年度雞苗運輸時間優(yōu)化及效率提升合同3篇
- 二零二五版?zhèn)€人汽車銷售代理合同模板3篇
- 二零二五年度二手汽車租賃與環(huán)保節(jié)能服務(wù)合同3篇
- 高處作業(yè)安全培訓(xùn)課件-
- 職中英語期末考試質(zhì)量分析
- 中國的世界遺產(chǎn)智慧樹知到答案章節(jié)測試2023年遼寧科技大學(xué)
- 急性腹瀉與慢性腹瀉修改版
- 先天性肌性斜頸的康復(fù)
- 《國際市場營銷》案例
- GB/T 37518-2019代理報關(guān)服務(wù)規(guī)范
- GB/T 156-2017標準電壓
- PPT溝通的藝術(shù)課件
- 內(nèi)科學(xué):巨幼細胞性貧血課件
- 暑假家校聯(lián)系情況記錄表
評論
0/150
提交評論