首页 > 代码库 > iOS 多线程 NSThread NSOperation NSOperationQueue GCD 线程锁 线程阻塞

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 =http://www.mamicode.com/ [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秒在运行

第二种设置线程阻塞
NSDate *date=[NSDate dateWithTimeIntervalSinceNow:4.0];
[NSThead sleepUntilDate:date];
 
线程锁经典案例卖火车票
 _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];//解锁            }    }

.........

iOS 多线程 NSThread NSOperation NSOperationQueue GCD 线程锁 线程阻塞