此示例的功能:使用gcd排序一个有4万数字的数组,数组中的数字都是随机生成的
生成数组代码如下
_numsMutableArray = [[NSMutableArray alloc] init]; for (int i = 0; i < 40000; i++) { NSNumber *temp = [NSNumber numberWithInt:arc4random_uniform(1000000)]; [_numsMutableArray addObject:temp]; }
生成的数字范围在0~一百万,再都添加到数组中。
非常简单粗暴地分4个线程,排序一个有这么多数字的数组,思路为,先多线程排序数组的不同部分,然后再合并,合并这里我就是再快排一次……因为我想不出什么好的合并方法。其实用了线程速度也没有什么提升……罢了,先练习怎么用objective-c的线程。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //创建一个线程队列 //下面这句就开辟了子线程 dispatch_async(queue, ^{ //调用类方法quickSort快速排序 [[self class] quickSort:self->_numsMutableArray low:0 high:10000]; });
用同样的方法开其他三个子线程。
dispatch_async(queue, ^{ //排序第1万位到第2万位之间的数组 [[self class] quickSort:self->_numsMutableArray low:10001 high:20000]; }); dispatch_async(queue, ^{ //排序第2万位到第3万位之间的数组 [[self class] quickSort:self->_numsMutableArray low:20001 high:30000]; }); dispatch_async(queue, ^{ //排序第3万位到第4万位之间的数组 [[self class] quickSort:self->_numsMutableArray low:30001 high:39999]; });
这样就可以让一个数组的四个部分有序,有序之后把这个四个部分再排序。
[[self class] quickSort:_numsMutableArray low:0 high:39999];
这样就完成了一个多线程练习。gcd属于是浅入门了。
那么现在可以观察一下,这些线程到底是不是并行。
//MARK: gcd dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ //排序 NSLog(@"10000"); [[self class] quickSort:self->_numsMutableArray low:0 high:10000]; NSLog(@"10001"); }); dispatch_async(queue, ^{ //排序 NSLog(@"20000"); [[self class] quickSort:self->_numsMutableArray low:10001 high:20000]; NSLog(@"20001"); }); dispatch_async(queue, ^{ //排序 NSLog(@"30000"); [[self class] quickSort:self->_numsMutableArray low:20001 high:30000]; NSLog(@"30001"); }); dispatch_async(queue, ^{ //排序 //这些log都在子线程中,40000代表进入线程,40001代表执行完毕。 NSLog(@"40000"); [[self class] quickSort:self->_numsMutableArray low:30001 high:39999]; NSLog(@"40001"); }); //这个log在主线程中 NSLog(@"jfkdslajflkdsj");
控制台输出为
2021-05-13 09:33:10.221206+0800 NSOperationPractice[6073:474997] jfkdslajflkdsj 2021-05-13 09:33:10.221214+0800 NSOperationPractice[6073:475037] 10000 2021-05-13 09:33:10.221219+0800 NSOperationPractice[6073:475034] 20000 2021-05-13 09:33:10.221229+0800 NSOperationPractice[6073:475033] 30000 2021-05-13 09:33:10.221250+0800 NSOperationPractice[6073:475036] 40000 2021-05-13 09:33:10.231717+0800 NSOperationPractice[6073:475036] 40001 2021-05-13 09:33:10.232100+0800 NSOperationPractice[6073:475037] 10001 2021-05-13 09:33:10.232303+0800 NSOperationPractice[6073:475033] 30001 2021-05-13 09:33:10.232469+0800 NSOperationPractice[6073:475034] 20001
多运行几次就会发现,这些线程开始和结束的时间并不是按1234顺序的,他们是并行执行的。而且,在主线程中的log尽管写在最后,也是最先输出的。如果我们要得到最大值最小值,思路应该是,在四个线程中得到最大值,然后比较这四个值,那么这四个值怎么取得呢?我们不能在这四个线程后面直接比较,因为上面说到,主线程是先执行的。所以要用到线程组的知识,我们创建四个线程,让代码等待这四个线程执行完毕之后,再来比较。
参考链接:https://www.jianshu.com/p/5fc974a951fd
之前写四个线程的时候,应该也有人觉得,一个一个的写太麻烦,现在就用for循环来写。
//创建一个线程队列 dispatch_queue_t concurrentQueue = dispatch_queue_create("com.group", DISPATCH_QUEUE_PRIORITY_DEFAULT); //用数组存4个最大值 NSMutableArray *tempArray = [[NSMutableArray alloc] init]; //创建一个线程组 dispatch_group_t group = dispatch_group_create(); for(int i = 0; i < 4; i++){ //在循环中创建4个线程 dispatch_group_async(group, concurrentQueue, ^{ //numsMutableArray是一个我自己写的类方法,里面找最大值,很简单,代码附在最后。 int t = [[self class] findTheMaxNumber:self->_numsMutableArray low:i * 10000 high:i * 10000 + 9999]; [tempArray addObject:@(t)]; // NSNumber *testNumb = [NSNumber numberWithInt:t];上一句的@(t)就是这句话的简写,创建了一个NSNumber对象。 }); } dispatch_group_notify(group, concurrentQueue, ^{ //子线程执行完毕可以进入这个代码块。 //NSLog(@"end"); //NSLog(@"%@",tempArray); int finallyMaxNumber = -1; for(int i = 0; i < 4; i++){ if(finallyMaxNumber < [[tempArray objectAtIndex:i] intValue]){ finallyMaxNumber = [[tempArray objectAtIndex:i] intValue]; } } NSLog(@"the max number %d",finallyMaxNumber); });
这样就实现了找最大值。
下面附上两个类方法的代码。
在AppDelegate.h中
+ (void)quickSort:(NSMutableArray *)array low:(int)low high:(int)high; + (int)findTheMaxNumber:(NSMutableArray *)array low:(int)low high:(int)high;
在AppDelegate.m中
+ (int)findTheMaxNumber:(NSMutableArray *)array low:(int)low high:(int)high{ int maxNumber = -10; for(int i = low; i < high; i++){ if(maxNumber < [array[i] intValue]){ maxNumber = [array[i] intValue]; } } return maxNumber; } //快速排序类方法 + (void)quickSort:(NSMutableArray *)array low:(int)low high:(int)high{ if(array == nil || array.count == 0){ return; } if(low >= high){ return; } int mid = low + (high - low)/2; NSNumber *prmt = array[mid]; int i = low; int j = high; while(i <= j){ while([array[i] intValue] < [prmt intValue]){ i++; } while([array[j] intValue] > [prmt intValue]){ j--; } if(i <= j){ [array exchangeObjectAtIndex:i withObjectAtIndex:j]; i++; j--; } } if(low < j){ [[self class]quickSort:array low:low high:j]; } if(high > i){ [[self class]quickSort:array low:i high:high]; } }
由于刚开始学Objective-C不能保证全部内容准确无误,如有错误欢迎留言。
Fin.