日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程——NSThread、GCD、NSOperation

發布時間:2025/4/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程——NSThread、GCD、NSOperation 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、前言:

一個應用程序就是一個進程,一個進程至少包含一個線程,程序啟動會自動創建一個主線程,負責UI界面的現實和控件事件的監控。多線程可以更充分的利用系統CPU資源,一定程度上提升程序的性能。1個進程可以開啟多條線程,每條線程可以并行(同時)執行不同的任務。在一個線程內可以包含多個事物(要干的活),在線程內依據先進先出的特性串行執行……

2、NSThread

- (void)viewDidLoad {[super viewDidLoad];NSLog(@"main thread is %@",[NSThread mainThread]);//打印主線程(UI線程) }-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{//新開辟一條子線程,啟動子線程的時候調用downLoad方法,object是傳遞給子線程調用方法的參數NSThread *thread=[[NSThread alloc] initWithTarget:self selector:@selector(downLoad:) object:@"luseike"];//給子線程起一個名字thread.name=@"thread one";//開始子線程[thread start]; }-(void)downLoad:(NSString *)param{//打印當前線程(子線程)及其名字和傳遞過來的參數NSLog(@"begin downLoad--param is %@--current thread is %@ current name is %@",param,[NSThread currentThread],[NSThread currentThread].name); }

?打印結果如下:

2014-06-26 23:03:05.724 NSThread[50292:60b] main thread is <NSThread: 0x8c421c0>{name = (null), num = 1}

2014-06-26 23:03:06.567 NSThread[50292:3807] begin downLoad--param is luseike--current thread is <NSThread: 0xa33c350>{name = thread one, num = 2} current name is thread one

可以看到主線程的num=1,子線程的num=2,證明確實是新開辟了一條線程來執行downLoad操作。

還可以通過isMainThread判斷是否是主線程,setThreadPriority:(double)p來設置子線程的優先級,優先級的取值范圍在0.0~1.0之間,默認是0.5,值越大,優先級越高,被執行的幾率越大

還有兩種比較便捷的方式來創建子線程

1、[NSThread detachNewThreadSelector:@selector(downLoad:) toTarget:self withObject:@"luseike"];//  附加一個線程

2、[self performSelectorInBackground:@selector(downLoad:) withObject:@"haha"];  //在后臺執行一個線程

這兩種方式創建的子線程都不需要調用start方法,系統會自動執行對應的方法,都也都沒有機會設置優先級和咸線程名等更詳細的設置了,不過這個一般不重要

3、線程的狀態

線程從生到死大致有下面幾種狀態:新建(new)、就緒(runnable)、運行(running)、阻塞(blocked)、死亡(dead)

一個線程被創建之后會放到一個叫做可調度線程池內,等待被CPU調度,當該線程獲得CPU的執行權時,就進入到running狀態。running狀態的線程如果調用sleep方法或者在等待同步鎖,就會進入阻塞狀態,進入阻塞狀態的線程會重新被放到可調度線程池內,等待被重新調度。線程任務執行完畢,或者被強制退出,會進入dead狀態,注意:進入dead狀態的線程并沒有被釋放內存,只是不能用了而已,還存在內存中。

?

4、控制線程的狀態

啟動線程:之前介紹過,調用start方法

阻塞(暫停)線程:

  + (void)sleepUntilDate:(NSDate *)date;

  + (void)sleepForTimeInterval:(NSTimeInterval)ti;

強制停止線程:+(void)exit;

多線程的安全隱患:當多個線程訪問同一塊資源時,很容易引發數據錯亂和數據安全問題。解決的機制就是使用鎖(互斥鎖),讓多條線程同步執行,這就是傳說的線程同步技術。值得注意的是:鎖定一份代碼只用1把鎖,用多把鎖是沒有意義的;線程同步的前提是多條線程搶占同一塊資源

#import "ViewController.h"@interface ViewController () @property(nonatomic,strong)NSThread *thread1; @property(nonatomic,strong)NSThread *thread2; @property(nonatomic,strong)NSThread *thread3;@property(nonatomic,assign)int totalCount; @end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];self.totalCount=100;self.thread1=[[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];self.thread2=[[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];self.thread3=[[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil]; }-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{[self.thread1 start];[self.thread2 start];[self.thread3 start]; }-(void)saleTicket{int leftCount=self.totalCount;while (leftCount>0) {self.totalCount=leftCount--;NSLog(@"%@ sale one ticket,left %d",[NSThread currentThread],leftCount);}
} @end

?如上代碼,模擬3個子線程同時訪問公共資源totalCount,每次操作減一,多線程訪問同一資源容易引起的數據安全問題已經說明了,打印部分結果如下

2014-06-26 23:51:33.639 NSThread[63065:360b] <NSThread: 0xa06dd50>{name = (null), num = 3} sale one ticket,left 99

2014-06-26 23:51:33.639 NSThread[63065:3707] <NSThread: 0xa0706e0>{name = (null), num = 2} sale one ticket,left 99

2014-06-26 23:51:33.639 NSThread[63065:3f03] <NSThread: 0xa06ddf0>{name = (null), num = 4} sale one ticket,left 99

可以看到三個子線程都操作了totalCount變量,每次操作之后的值卻沒有變化……

互斥鎖的使用格式:

@synchronized(鎖對象) { // 需要鎖定的代碼? }

-(void)saleTicket{while (1) {@synchronized(self) { // 加鎖(只能用一把鎖)// 1.先檢查票數int count = self.totalCount;if (count > 0) {self.totalCount = count - 1;NSThread *current = [NSThread currentThread];NSLog(@"%@ sale one ticket, left %d tickets", current, self.totalCount);} else {[NSThread exit];}} } }

?打印結果就可以正常顯示了……

5、GCD簡介

GCD是蘋果為了多核的并行運算提出的解決方案,會自動管理線程的生命周期,程序員只需要告訴GCD要執行什么任務,不需要編寫任何線程管理代碼。GCD中兩個核心概念:任務、隊列,將任務添加到隊列中,GCD會自動將隊列中的任務取出,放到對應的線程中執行,任務的取出遵循隊列FIFO原則:先進先出,后進后出。

GCD的隊列可以分為2大類型:并發隊列(可以讓多個任務并發執行)、串行隊列

?

轉載于:https://www.cnblogs.com/luseike/p/3811128.html

總結

以上是生活随笔為你收集整理的多线程——NSThread、GCD、NSOperation的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。