1. NSThread的三種創(chuàng)建方法
//方式一 對(duì)象方法
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
//線程名稱
//作用:可以快速找到出錯(cuò)的線程
thread.name = @"test";
//優(yōu)先級(jí)0-1,默認(rèn)0.5
//優(yōu)先級(jí)高代表cpu在該線程調(diào)度所用的時(shí)間多
thread.threadPriority = 1.0;
[thread start];
//方式二 類方法
[NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
//方式三
[self performSelectorInBackground:@selector(test) withObject:nil];
- (void)test {
NSLog(@"%@",[NSThread currentThread]);
}
2.NSThread的幾種狀態(tài)
新建-就緒-運(yùn)行-阻塞-銷毀
//新建
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
//就緒
[thread start];
- (void)test {
//線程運(yùn)行是由cpu控制的,結(jié)束之后會(huì)自動(dòng)銷毀
//下面是模擬狀態(tài)
for (int i = 0; i < 20; i ++) {
if (i == 5) {
//線程阻塞
[NSThread sleepForTimeInterval:2.0];
}
if (i == 10) {
//線程主動(dòng)銷毀
[NSThread exit];
}
}
}
3.線程的資源共享(不安全)
舉例:賣火車票,票數(shù)總共10張,兩個(gè)窗口同時(shí)賣
代碼檢驗(yàn):
@property (nonatomic, assign) NSInteger ticketsCount;//總票數(shù)
self.ticketsCount = 10;
//創(chuàng)建二個(gè)線程
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(sellTickets) object:nil];
[thread1 start];
NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(sellTickets) object:nil];
[thread2 start];
- (void)sellTickets {
while (1) {
//模擬耗時(shí)
[NSThread sleepForTimeInterval:1.0];
if (self.ticketsCount > 0) {
self.ticketsCount--;
NSLog(@"剩余%ld張",self.ticketsCount);
} else {
NSLog(@"票已賣完");
break;
}
}
}
輸出結(jié)果:從以下圖中可以看出輸出是無(wú)序的,讀寫出錯(cuò),也就是線程不安全

D8D06852-22FE-4539-9189-CD66D7391799.png
解決方案:給數(shù)據(jù)的讀寫操作加把互斥鎖
- (void)sellTickets {
while (1) {
//模擬耗時(shí)
[NSThread sleepForTimeInterval:1.0];
//同步
//默認(rèn)打開(kāi)鎖,進(jìn)入之后會(huì)關(guān)閉鎖,直到結(jié)束才打開(kāi)鎖
@synchronized (self) {
if (self.ticketsCount > 0) {
self.ticketsCount--;
NSLog(@"剩余%ld張",self.ticketsCount);
} else {
NSLog(@"票已賣完");
break;
}
}
}
}
輸出效果:有序的執(zhí)行,保證了線程的安全,但是性能會(huì)降低

image.png