iOS 多线程 NSThread NSOperation NSOperationQueue GCD 线程锁 线程阻塞
iPhone中的线程应用并不是无节制的,官方给出的资料显示,iPhone OS下的主线程的堆栈大小是1M,第二个线程开始就是512KB,并且该值不能通过编译器开关或线程API函数来更改,只有主线程有直接修改UI的能力,所以一些数据层面可以开辟线程来操作进行,iOS线程的操作方法有NSThread NSOperation NSOperationQueue GCD:
NSThread方法有
//NSThread自动 - (IBAction)didClickNSThreadAutoButtonAction:(id)sender { //创建一个子线程,即子线程 //selector在子线程中运行方法,target在子线程执行方法对象,object是方法参数 [NSThread detachNewThreadSelector:@selector(cycle) toTarget:self withObject:nil]; } //NSthread手动 - (IBAction)didClickNSThreadHandButtonAction:(id)sender { NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(cycle) object:nil]; [thread start];//手动开启线程 }
通过NSObject的类目方法,直接创建线程
//NSOperation invocation方法创建线程 - (IBAction)didClickInvocationButtonAction:(id)sender { //操作对象,封装方法实现和数据 NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(cycle) object:nil]; [operation start];//开始执行operation中存储的方法 }
使用NSOperation方法
//NSOperation invocation方法创建线程 - (IBAction)didClickInvocationButtonAction:(id)sender { //操作对象,封装方法实现和数据 NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(cycle) object:nil]; [operation start];//开始执行operation中存储的方法 } //NSOperation block方法 - (IBAction)didClickBlockButtonAction:(id)sender { NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ //封装要执行的方法 for (int i = 0 ; i < 10; i++) { NSLog(@"当前线程 == %@ 是否是主线程 == %d i : %d",[NSThread currentThread],[NSThread isMainThread],i); } }]; //执行方法 [operation start]; }
使用NSOperationQueue 线程列队
//NSOperationQueue 创建线程队列 - (IBAction)didClickOperationQueueButtonAction:(id)sender { //线程区分:脱离线程和非脱离线程 //脱离线程:线程中的功能实现完成后,线程会会被关闭销毁.NSThread NSObject类目方法创建的线程.默认是脱离线程 //非脱离线程:线程中的功能实现后,线程进入睡眠状态,等待再次使用. 脱离线程中的runloop运行且不在关闭,则变成非脱离线程. NSOperationQueue创建的线程是非脱离线程. //操作队列实现多个线程并发执行. //线程同步:当前一个线程执行完成后,下一个线程在执行开始. //如何实现线程同步:将操作队列的最大并发数设置成1; //创建线程队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; //设置操作队列同时最大线程并发个数 queue.maxConcurrentOperationCount = 5; for (int i = 0; i < 10; i++) { NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(cycle) object:nil]; //添加到线程队列中 [queue addOperation:operation]; [operation release]; } }
使用GCD方法出行队列
//GCD串行队列 - (IBAction)didClickSerialButtonAction:(id)sender { //串行队列有两种 //mainQueue主队列,GCD创建并提供,在主队列中默认是串行队列,并且按照代码顺序执行 dispatch_queue_t mainQueue = dispatch_get_main_queue(); //向主队列添加任务,参数一 :管理任务的队列 参数二:封装任务代码的block dispatch_async(mainQueue, ^{ NSLog(@"第一个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(mainQueue, ^{ NSLog(@"第二个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(mainQueue, ^{ NSLog(@"第三个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(mainQueue, ^{ NSLog(@"第四个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(mainQueue, ^{ NSLog(@"第五个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); //在定义队列,需要自己创建,并设置为串行 DISPATCH_QUEUE_SERIAL串行接口 // dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL); // // dispatch_async(queue, ^{ // NSLog(@"第一个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第二个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第三个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第四个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第五个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); }
使用GCD并行队列
//GCD并行队列 - (IBAction)didClickConcurrentButtonAction:(id)sender { //并行队列有两种 //全局队列,CGD创建 // dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // // dispatch_async(queue, ^{ // NSLog(@"第一个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第二个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第三个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第四个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); // dispatch_async(queue, ^{ // NSLog(@"第五个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); // }); //自定义队列,需要自己创建,并设置并行队列 DISPATCH_QUEUE_CONCURRENT并行接口 dispatch_queue_t queue = dispatch_queue_create("concurrent queue", DISPATCH_QUEUE_CONCURRENT); //添加任务 dispatch_async(queue, ^{ NSLog(@"第一个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"第二个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"第三个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"第四个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"第五个任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); }); }
使用GCD下载图片实际操作
//实际下载图片操作 - (IBAction)didClickGCDownloadButtonAction:(id)sender { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //将任务添加到全局队列中,可以被派发到子线程中执行 dispatch_async(queue, ^{ //这是子线程中 NSString *imageUrl = @"http://a.hiphotos.baidu.com/image/pic/item/96dda144ad3459824a56a41a0ef431adcaef845e.jpg"; NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]]; UIImage *image = [UIImage imageWithData:data]; NSLog(@"image = %@",image); NSLog(@"任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); //在主线程显示图像 //把任务添加到主队列中,主队列将任务派发到主线程中 dispatch_async(dispatch_get_main_queue(), ^{ //现在是主线程 NSLog(@"任务===%@ 所在线程===%d",[NSThread currentThread],[NSThread isMainThread]); _imageView.image = image; }); }); }
线程阻塞方法第一种:
[NSThread sleepForInterval:2.0]//意识是该线程等待2秒在运行
_lock = [[NSLock alloc]init];//创建互斥锁,多个线程共享使用
//卖火车票 - (void)saleTickets:(dispatch_queue_t)queue { while (_surplusCount > 0) { [_lock lock];//获取互斥锁 //每次执行休眠0.1秒 [NSThread sleepForTimeInterval:0.1]; const char *queueLabel = dispatch_queue_get_label(queue); NSString *label = [NSString stringWithUTF8String:queueLabel]; NSLog(@"当前火车票由 %@ 售出 余票: %d 张",label,_surplusCount); _surplusCount--; [_lock unlock];//解锁 } }
.........
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。