03-Pthread | NSThread
標簽: 面試基礎知識(多線程)
01-pthread的基本使用(需要包含頭文件)
//使用pthread創(chuàng)建線程對象
pthread_t thread;
NSString *name = @"wendingding";
//使用pthread創(chuàng)建線程
//第一個參數(shù):線程對象地址
//第二個參數(shù):線程屬性
//第三個參數(shù):指向函數(shù)的指針
//第四個參數(shù):傳遞給該函數(shù)的參數(shù)
pthread_create(&thread, NULL, run, (__bridge void *)(name));
pthread_exit(NULL); // 退出當前線程
02-NSThread的基本使用
(1)線程的創(chuàng)建
第一種創(chuàng)建線程的方式:alloc init.
//特點:需要手動開啟線程,可以拿到線程對象進行詳細設置
//創(chuàng)建線程
/*
第一個參數(shù):目標對象
第二個參數(shù):選擇器,線程啟動要調用哪個方法
第三個參數(shù):前面方法要接收的參數(shù)(最多只能接收一個參數(shù),沒有則傳nil)
*/
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"wendingding"];
//啟動線程
[thread start];
第二種創(chuàng)建線程的方式:分離出一條子線程
//特點:自動啟動線程捶枢,無法對線程進行更詳細的設置
/*
第一個參數(shù):線程啟動調用的方法
第二個參數(shù):目標對象
第三個參數(shù):傳遞給調用方法的參數(shù)
*/
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"我是分離出來的子線程"];
第三種創(chuàng)建線程的方式:后臺線程
//特點:自動啟動縣城刹缝,無法進行更詳細設置
[self performSelectorInBackground:@selector(run:) withObject:@"我是后臺線程"];
(2)設置線程的屬性
//設置線程的名稱
thread.name = @"線程A";
//設置線程的優(yōu)先級,注意線程優(yōu)先級的取值范圍為0.0~1.0之間萤捆,1.0表示線程的優(yōu)先級最高,如果不設置該值姊舵,那么理想狀態(tài)下默認為0.5
thread.threadPriority = 1.0;
(3) 線程的狀態(tài)(了解)
//線程的各種狀態(tài):新建-就緒-運行-阻塞-死亡
//常用的控制線程狀態(tài)的方法
[NSThread exit];//退出當前線程
[NSThread sleepForTimeInterval:2.0];//阻塞線程
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];//阻塞線程
//注意:線程死了不能復生
(4) 線程安全
- 前提:多個線程訪問同一塊資源會發(fā)生數(shù)據(jù)安全問題
- 解決方案:加互斥鎖
- 相關代碼:
@synchronized(self){}
- 專業(yè)術語-線程同步
- 原子和非原子屬性(是否對setter方法加鎖)
(5) 線程間通信
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
//開啟一條子線程來下載圖片
[NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil];
}
-(void)downloadImage
{
//1.確定要下載網(wǎng)絡圖片的url地址,一個url唯一對應著網(wǎng)絡上的一個資源
NSURL *url = [NSURL URLWithString:@"http://p6.qhimg.com/t01d2954e2799c461ab.jpg"];
//2.根據(jù)url地址下載圖片數(shù)據(jù)到本地(二進制數(shù)據(jù)
NSData *data = [NSData dataWithContentsOfURL:url];
//3.把下載到本地的二進制數(shù)據(jù)轉換成圖片
UIImage *image = [UIImage imageWithData:data];
//4.回到主線程刷新UI
4.1 第一種方式
// [self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
4.2 第二種方式
// [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
4.3 第三種方式
[self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
}
(6) 如何計算代碼段的執(zhí)行時間
第一種方法
NSDate *start = [NSDate date];
//2.根據(jù)url地址下載圖片數(shù)據(jù)到本地(二進制數(shù)據(jù))
NSData *data = [NSData dataWithContentsOfURL:url];
NSDate *end = [NSDate date];
NSLog(@"第二步操作花費的時間為%f",[end timeIntervalSinceDate:start]);
第二種方法
CFTimeInterval start = CFAbsoluteTimeGetCurrent();
NSData *data = [NSData dataWithContentsOfURL:url];
CFTimeInterval end = CFAbsoluteTimeGetCurrent();
NSLog(@"第二步操作花費的時間為%f",end - start);