1. NSThread的三种创建方法
//方式一 对象方法
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
//线程名称
//作用:可以快速找到出错的线程
thread.name = @"test";
//优先级0-1,默认0.5
//优先级高代表cpu在该线程调度所用的时间多
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的几种状态
新建-就绪-运行-阻塞-销毁
//新建
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
//就绪
[thread start];
- (void)test {
//线程运行是由cpu控制的,结束之后会自动销毁
//下面是模拟状态
for (int i = 0; i < 20; i ++) {
if (i == 5) {
//线程阻塞
[NSThread sleepForTimeInterval:2.0];
}
if (i == 10) {
//线程主动销毁
[NSThread exit];
}
}
}
3.线程的资源共享(不安全)
举例:卖火车票,票数总共10张,两个窗口同时卖
代码检验:
@property (nonatomic, assign) NSInteger ticketsCount;//总票数
self.ticketsCount = 10;
//创建二个线程
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;
}
}
}
输出结果:从以下图中可以看出输出是无序的,读写出错,也就是线程不安全
D8D06852-22FE-4539-9189-CD66D7391799.png
解决方案:给数据的读写操作加把互斥锁
- (void)sellTickets {
while (1) {
//模拟耗时
[NSThread sleepForTimeInterval:1.0];
//同步
//默认打开锁,进入之后会关闭锁,直到结束才打开锁
@synchronized (self) {
if (self.ticketsCount > 0) {
self.ticketsCount--;
NSLog(@"剩余%ld张",self.ticketsCount);
} else {
NSLog(@"票已卖完");
break;
}
}
}
}
输出效果:有序的执行,保证了线程的安全,但是性能会降低
image.png