1. NSThread的三種創(chuàng)建方法
//方式一 對象方法
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
//線程名稱
//作用:可以快速找到出錯的線程
thread.name = @"test";
//優(yōu)先級0-1,默認0.5
//優(yōu)先級高代表cpu在該線程調(diào)度所用的時間多
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)
新建-就緒-運行-阻塞-銷毀
//新建
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
//就緒
[thread start];
- (void)test {
//線程運行是由cpu控制的蜕窿,結(jié)束之后會自動銷毀
//下面是模擬狀態(tài)
for (int i = 0; i < 20; i ++) {
if (i == 5) {
//線程阻塞
[NSThread sleepForTimeInterval:2.0];
}
if (i == 10) {
//線程主動銷毀
[NSThread exit];
}
}
}
3.線程的資源共享(不安全)
舉例:賣火車票尚镰,票數(shù)總共10張博秫,兩個窗口同時賣
代碼檢驗:
@property (nonatomic, assign) NSInteger ticketsCount;//總票數(shù)
self.ticketsCount = 10;
//創(chuàng)建二個線程
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) {
//模擬耗時
[NSThread sleepForTimeInterval:1.0];
if (self.ticketsCount > 0) {
self.ticketsCount--;
NSLog(@"剩余%ld張",self.ticketsCount);
} else {
NSLog(@"票已賣完");
break;
}
}
}
輸出結(jié)果:從以下圖中可以看出輸出是無序的派任,讀寫出錯晒他,也就是線程不安全
D8D06852-22FE-4539-9189-CD66D7391799.png
解決方案:給數(shù)據(jù)的讀寫操作加把互斥鎖
- (void)sellTickets {
while (1) {
//模擬耗時
[NSThread sleepForTimeInterval:1.0];
//同步
//默認打開鎖赶诊,進入之后會關(guān)閉鎖笼平,直到結(jié)束才打開鎖
@synchronized (self) {
if (self.ticketsCount > 0) {
self.ticketsCount--;
NSLog(@"剩余%ld張",self.ticketsCount);
} else {
NSLog(@"票已賣完");
break;
}
}
}
}
輸出效果:有序的執(zhí)行,保證了線程的安全舔痪,但是性能會降低
image.png