线程和 进程
每一个应用程序都可以看做一个进程,每一个进程可以包含多个线程,但是至少有一个线程(一般由系统默认创建)我们称之为主线程.如果想要多线程去完成多任务工作需要我们手动开辟创建子线程 一般我们将耗时的操作放入子线程进行,对于UI界面的刷新,我们仍然在主线程中工作,否则会发生灵异现象
关于多线程的好处 和坏处
好处:
1.使用多线程可以把程序中的耗时操作放入子线程进行后台处理,比如网络请求,图片的下载
2.发挥多核处理器的优势,让程序执行更加流畅,更加迅速用户体验好
坏处:
1.大量的线程开辟降低代码的可读性
2.线程的开辟就意味着需要更多的空间
3.在进行多线程工作,会发生多个线程对统一资源进行抢夺,发生线程安全问题
对于网络请求 可以放在子线程进行操作但是对于UI界面的刷新重新赋值需要回到主线程进行
#pragma mark - 子线程开辟 第一种方式使用 NSThread
//[NSThread currentThread] 获取当前的线程
//[NSThread isMainThread] 判断当前的线程是否是主线程
NSLog(@"%@ ----- %d",[NSThread currentThread],[NSThread isMainThread]);
//1.使用类方法 开辟子线程
[NSThread detachNewThreadSelector:@selector(print1) toTarget:self withObject:nil];
[NSThread detachNewThreadSelector:@selector(print2) toTarget:self withObject:nil];
//2.创建对象 开辟子线程
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(print1) object:nil];
NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(print2) object:nil];
//开启子线程 并执行任务
[thread1 start];
[thread2 start];
#pragma mark - 开辟子线程的 第二种方法 使用NSObject提供的方法
[self performSelectorInBackground:@selector(print1) withObject:self];
[self performSelectorInBackground:@selector(print2) withObject:self];
#pragma mark - 开辟子线程的第三种方式 NSOperationQueue
//创建任务 NSOperation
//1.使用block 创建任务
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@ ------ %d 任务1",[NSThread currentThread],[NSThread isMainThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@ ------ %d 任务2",[NSThread currentThread],[NSThread isMainThread]);
}];
//2.使用NSInvocationOperation 创建任务
NSInvocationOperation *operation3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action1) object:nil];
NSInvocationOperation *operation4 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action2) object:nil];
//创建任务队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// //控制开辟线程个数
// queue.maxConcurrentOperationCount = 1;
//
//
// //添加任务
// [queue addOperation:operation1];
// [queue addOperation:operation2];
// [queue addOperation:operation3];
// [queue addOperation:operation4];
//线程重用问题
for (int i = 0; i < 20; i++) {
//创建任务
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@------------------%d 任务%d",[NSThread currentThread],[NSThread isMainThread],i);
}];
//添加到任务队列
[queue addOperation:operation];
}
串行 多个任务执行时,只能一个一个执行.比如,只有当第一个任务执行完,第二个才能执行,接着是第三个...
- (IBAction)serialQueue:(id)sender {
//1.系统创建串行队列
dispatch_queue_t systemQueue = dispatch_get_main_queue();
dispatch_async(systemQueue, ^{
NSLog(@"%@ --- %d 任务1",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(systemQueue, ^{
NSLog(@"%@ --- %d 任务2",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(systemQueue, ^{
NSLog(@"%@ --- %d 任务3",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(systemQueue, ^{
NSLog(@"%@ --- %d 任务4",[NSThread currentThread],[NSThread isMainThread]);
});
//2.自己创建串行队列
//第一个参数给定一个标识
//第二个参数给定当前创建队列的属性
dispatch_queue_t queue = dispatch_queue_create("com.lanou.www", DISPATCH_QUEUE_SERIAL);
//任务添加
dispatch_async(queue, ^{
NSLog(@"%@ --- %d 任务1",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"%@ --- %d 任务2",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"%@ --- %d 任务3",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"%@ --- %d 任务4",[NSThread currentThread],[NSThread isMainThread]);
});
}
并行 建议使用系统创建的
- (IBAction)concurrentQueue:(id)sender {
//1.使用系统创建的并行队列
dispatch_queue_t systemQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//添加 任务
//第一个参数 设置优先级
//第二个参数 预留参数 当前给0
dispatch_async(systemQueue, ^{
NSLog(@"%@-----%d 任务1",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(systemQueue, ^{
NSLog(@"%@-----%d 任务2",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(systemQueue, ^{
NSLog(@"%@-----%d 任务3",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(systemQueue, ^{
NSLog(@"%@-----%d 任务4",[NSThread currentThread],[NSThread isMainThread]);
});
//2.自己创建并行队列
dispatch_queue_t myQueue = dispatch_queue_create("com.xilanhua.www", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
NSLog(@"%@-----%d 任务1",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"%@-----%d 任务2",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"%@-----%d 任务3",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_async(myQueue, ^{
NSLog(@"%@-----%d 任务4",[NSThread currentThread],[NSThread isMainThread]);
});
}
//分组
- (IBAction)group:(id)sender {
//创建分组
dispatch_group_t group = dispatch_group_create();
//使用系统创建并行队列
dispatch_queue_t systemQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//添加任务
dispatch_group_async(group, systemQueue, ^{
NSLog(@"%@-----%d 任务1",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_group_async(group, systemQueue, ^{
NSLog(@"%@-----%d 任务2",[NSThread currentThread],[NSThread isMainThread]);
});
dispatch_group_async(group, systemQueue, ^{
NSLog(@"%@-----%d 任务3",[NSThread currentThread],[NSThread isMainThread]);
});
//当分组中所有任务完成时 执行
dispatch_group_notify(group, systemQueue, ^{
NSLog(@"分组中的任务全部完成");
});
}
//障碍
- (IBAction)barrier:(id)sender {
//创建自己的并行队列
dispatch_queue_t myQueue = dispatch_queue_create("com.kongxincai.www", DISPATCH_QUEUE_CONCURRENT);
//加载过程
dispatch_async(myQueue, ^{
NSLog(@"A 加载...");
});
dispatch_async(myQueue, ^{
NSLog(@"B 加载...");
});
dispatch_async(myQueue, ^{
NSLog(@"C 加载...");
});
dispatch_barrier_async(myQueue, ^{
NSLog(@"全部加载完成,开始进入游戏...");
});
//进入游戏
dispatch_async(myQueue, ^{
NSLog(@"A 进入游戏");
});
dispatch_async(myQueue, ^{
NSLog(@"B 进入游戏");
});
dispatch_async(myQueue, ^{
NSLog(@"C 进入游戏");
});
dispatch_barrier_async(myQueue, ^{
NSLog(@"全部进入游戏");
//回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"敌军还有30秒钟到达战场,碾碎他们");
});
});
}
//一次
- (IBAction)once:(id)sender {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"First Blood!");
});
}
- (IBAction)buyTicket:(id)sender {
//创建并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 11; i++) {
dispatch_async(queue, ^{
[self buy];
});
}
}
//购买
-(void)buy
{
static int count = 10; //10张票
//加锁
[_lock lock];
if (count <= 0) {
NSLog(@"没票了");
}else
{
count --;//每买一次 票数-1
NSLog(@"购买第%d张票",10-count);
}
//解锁
[_lock unlock];
}