1.多线程的使用
耗时的操作放在子线程(非主线程,后台线程)
如果把耗时的操作放在主线程就会造成卡顿现象
只有打印10000次以后,卡顿现象才会消失,textView内容才能滑动
1.主线程只有一条,是苹果帮我们自动创建的,UI的展示都是在主线程显示,我们能开的只是子线程.
2.iOS中多线程的实现方案
2.1 pthread
2.2 NSThread
2.3 GCD
2.4 NSOperation
这几种方法的使用情况和使用频率用下面的表格提现
2.多线程的创建
1.通过NSThread创建的三种方法
2.线程的优先级
thread.threadPriority=1.0;
它的取值范围0-1,1的优先级最高,默认线程的优先级值为0.5
3. 创建线程的后两种方法,设置不了线程的属性,和线程进行的优先级,所以创建线程的时候,根据实际情况来创建.
2.多线程的状态
2.线程安全
1. 多条线程共享一块资源的时候就会出现线程安全问题,这时候我们就需要加锁(互斥锁)
2. 加锁后,线程执行是按顺序的,同步进行及线程同步
3. 加锁后会消耗一定的CPU资源
代码执行如下
/**线程A */
@property(nonatomic,strong)NSThread*threadA;
/**线程B */
@property(nonatomic,strong)NSThread*threadB;
/**线程C */
@property(nonatomic,strong)NSThread*threadC;
/**票数*/
@property(nonatomic,assign)NSIntegertotalCount;
@end
@implementationViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event
{
//假设总票数
self.totalCount=100;
//创建线程
self.threadA= [[NSThreadalloc]initWithTarget:selfselector:@selector(soaldTickit)object:nil];
self.threadB= [[NSThreadalloc]initWithTarget:selfselector:@selector(soaldTickit)object:nil];
self.threadC= [[NSThreadalloc]initWithTarget:selfselector:@selector(soaldTickit)object:nil];
//设置线程名称
self.threadA.name=@"服务小姐A";
self.threadB.name=@"服务小姐B";
self.threadC.name=@"服务小姐C";
//开启线程
[self.threadAstart];
[self.threadBstart];
[self.threadCstart];
}
-(void)soaldTickit
{
//多条线程共享一块资源的时候需要加锁,互斥锁
//加互斥锁,线程同步,有序进行
//但加锁的同时,会消耗大量CPU资源
while(1) {
@synchronized(self) { //锁:必须是全局唯一的
NSIntegercount =self.totalCount;
if(count >0) {
for(NSIntegeri =0; i<10000000; i++) {
}
self.totalCount= count -1;//卖出一张票,则减一张
NSLog(@"%@------剩余%zd张票",[NSThreadcurrentThread].name,self.totalCount);
}else{
NSLog(@"没票了");
break;
}
}
}
}
4.原子属性,非原子属性
1.atomic则是原子属性
nonatamic 非原子属性
原子属性则会默认为setter方法加锁,线程安全,但会消耗大量资源
非原子属性,不会为setter方法加锁,非线程安全,但消耗资源少,适合内存小的设备
那么既然线程不安全,为什么我们在项目中还用呢?
因为在项目中很少会出现一块资源多条线程共享的情况,如果真的有,需要用的时候就写atomic
5.线程间通信
1.如果加载大量图片,在子线程下载完以后,需要显示在UI界面.但显示UI界面是在主线程,这时候就需要线程间的通信,图片下载完以后,就需要告诉说我下载完了,可以展示了.
代码如下