什么是多线程:
什么是进程 ?
想说清什么是多线程,我们还需要了解一些其他的东西,什么是进程,网上大多数资料解释是一个运行中的应用程序,举个例子,比如电脑上运行的QQ,微信。。。是不是感觉有点抽象,这样去想,不管是QQ还是微信他们只是一个应用程序,应用程序运行需要内存存储一些东西,比如变量常量方法函数。。。这些东西运行需要执行顺序和计算,然后根据我们编程逻辑在屏幕上显示出我们所想要的东西,计算机上有若干个应用程序,我们不能任由他们在内存或CPU上乱搞吧,这样不就混乱了,因此程序在运行时会创建一个属于自己的空间,在这个空间里做自己想要做的事情,那么这个空间就是我们要说的进程。
__ 什么是线程 ?__
说了这么多,可能有人会问这和多线程有毛关系,再说这个毛关系之前我们先理清什么是线程,网上大多数资料的解释是把一堆要执行的指令串联起来称为线程,这又是什么鬼东西,好了这确实不是什么鬼东西,说清楚就好了,举个QQ登录的例子,我们一般打开QQ登录进入之后才能看到我们的好友,这句话我们分析下是怎么回事,我们要看到我们的QQ好友,那么我们必须输入账号密码,再去点击登录按钮,然后我们就看到我们的QQ好友了,是不是这些操作就像一条线一样贯穿我们最终看到QQ好友,明白线程了吧。
什么是多线程 ?
我们再来看看多线程,网上解释是同一时刻有多条线程执行我们称为多线程,说到这里有人又开始糊涂了,CPU不是一个核心吗,一次只能执行一条线程,怎么突然又跑出多个线程来,不符合科学呀,不要激动,我解释下,首先我肯定一点你所说的是正确的,看来你对CPU的执行还算了解,其实说到底CPU同时还是在执行一个线程,那又是怎么同时执行多条线程了,他会把多个线程切分成小块,因为运行速度特别快,他每秒可能从多个线程中个取出一块来执行,造成我们视觉的效果就是同一时刻就好像有多条线程在执行。
IOS中的多线程#####
IOS中常用到的多线程处理有三个:
- NSThread
- GCD
- NSOperation/NSOperationQueue
NSThread:
GCD:
GCD是苹果多核编程处理的解决方案,底层通过纯C语言实现。在开始学习GCD时首先必须了解几个概念:
1.任务:做什么操作,实现什么功能。
1.1 同步操作:多个任务执行中,会阻碍下一个任务执行,直到第一个任务执行完成,才会执行下一个任务。
1.2 异步操作:多个任务执行中,相互不受影响,各执行个的任务。
2.队列:将定义的任务存放起来。
2.1 串行队列:队列中的任务执行通道只有一条,同一时刻只会执行一个任务。
2.2 并行队列:队列中的任物执行通道有多条,同一时刻会执行多个任务。
GCD中基本对象的创建
// 创建串行队列
dispatch_queue_t queue1 = dispatch_queue_create("tk.bournetestQueue", NULL);
dispatch_queue_t queue2 = dispatch_queue_create("tk.bournetestQueue", DISPATCH_QUEUE_SERIAL);
// 创建并行队列
dispatch_queue_t queue3 = dispatch_queue_create("tk.bournetestQueue", DISPATCH_QUEUE_CONCURRENT);
// DISPATCH_QUEUE_PRIORITY_HIGH //高
// DISPATCH_QUEUE_PRIORITY_DEFAULT //默认(中)
// DISPATCH_QUEUE_PRIORITY_LOW // 底
// DISPATCH_QUEUE_PRIORITY_BACKGROUND // 后台
// 创建全局并行队列
dispatch_queue_t queue4 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
// 创建主线程
dispatch_queue_t queue5 = dispatch_get_main_queue();
// 创建同步任务
dispatch_sync(queue1, ^{
//do some thing ...
});
// 创建异步任务
dispatch_async(queue2, ^{
// do some thing ...
});
测试
// 事例1(串行队列 异步执行)
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 总结:创建新的线程
// 2016-07-04 14:47:29.348 多线程Demo[1914:96867] current thread<NSThread: 0x100306210>{number = 1, name = main}
// 2016-07-04 14:47:29.350 多线程Demo[1914:96891] download image1 <NSThread: 0x100308580>{number = 2, name = (null)}
// 2016-07-04 14:47:29.351 多线程Demo[1914:96891] download image2 <NSThread: 0x100308580>{number = 2, name = (null)}
// 2016-07-04 14:47:29.351 多线程Demo[1914:96891] download image3 <NSThread: 0x100308580>{number = 2, name = (null)}
// 事例2(并行队列 异步执行)
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 总结:创建新的线程
// 2016-07-04 14:49:56.728 多线程Demo[1940:98159] current thread<NSThread: 0x100502b50>{number = 1, name = main}
// 2016-07-04 14:49:56.731 多线程Demo[1940:98189] download image1 <NSThread: 0x100108560>{number = 2, name = (null)}
// 2016-07-04 14:49:56.731 多线程Demo[1940:98189] download image2 <NSThread: 0x100108560>{number = 2, name = (null)}
// 2016-07-04 14:49:56.731 多线程Demo[1940:98189] download image3 <NSThread: 0x100108560>{number = 2, name = (null)}
// 事例3(串行队列 同步执行)
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 总结:不会创建新的线程
// 2016-07-04 14:52:42.806 多线程Demo[1965:99334] current thread<NSThread: 0x1002063b0>{number = 1, name = main}
// 2016-07-04 14:52:42.807 多线程Demo[1965:99334] download image1 <NSThread: 0x1002063b0>{number = 1, name = main}
// 2016-07-04 14:52:42.807 多线程Demo[1965:99334] download image2 <NSThread: 0x1002063b0>{number = 1, name = main}
// 2016-07-04 14:52:42.807 多线程Demo[1965:99334] download image3 <NSThread: 0x1002063b0>{number = 1, name = main}
// 事例4(并行队列 同步执行)
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 总结:不会创建新的线程
// 2016-07-04 14:53:49.116 多线程Demo[1982:99780] current thread<NSThread: 0x100105010>{number = 1, name = main}
// 2016-07-04 14:53:49.117 多线程Demo[1982:99780] download image1 <NSThread: 0x100105010>{number = 1, name = main}
// 2016-07-04 14:53:49.117 多线程Demo[1982:99780] download image2 <NSThread: 0x100105010>{number = 1, name = main}
// 2016-07-04 14:53:49.117 多线程Demo[1982:99780] download image3 <NSThread: 0x100105010>{number = 1, name = main}
// 事例5(主线程,异步执行)
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_async(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 总结:不会创建新的线程
// 2016-07-04 14:58:01.040 多线程Demo[2023:101512] current thread<NSThread: 0x100602b50>{number = 1, name = main}
// 2016-07-04 14:58:01.042 多线程Demo[2023:101512] download image1 <NSThread: 0x100602b50>{number = 1, name = main}
// 2016-07-04 14:58:01.042 多线程Demo[2023:101512] download image2 <NSThread: 0x100602b50>{number = 1, name = main}
// 2016-07-04 14:58:01.042 多线程Demo[2023:101512] download image3 <NSThread: 0x100602b50>{number = 1, name = main}
// 事例6(主线程,同步操作)
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 结论:主线程的同步操作,
// 2016-07-04 14:58:55.638 多线程Demo[2041:101984] current thread<NSThread: 0x100202cc0>{number = 1, name = main}
// 事例7(全局,同步操作)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 结论:不会创建新线程
// 2016-07-04 15:03:41.035 多线程Demo[2078:103856] current thread<NSThread: 0x1002050b0>{number = 1, name = main}
// 2016-07-04 15:03:41.036 多线程Demo[2078:103856] download image1 <NSThread: 0x1002050b0>{number = 1, name = main}
// 2016-07-04 15:03:41.036 多线程Demo[2078:103856] download image2 <NSThread: 0x1002050b0>{number = 1, name = main}
// 2016-07-04 15:03:41.036 多线程Demo[2078:103856] download image3 <NSThread: 0x1002050b0>{number = 1, name = main}
// 事例8(全局,异步操作)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"current thread%@",[NSThread currentThread]);
dispatch_async(queue, ^{
NSLog(@"download image1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download image3 %@",[NSThread currentThread]);
});
// 结论:会创建新线程,每个任务都会创建一个线程
// 2016-07-04 15:05:02.274 多线程Demo[2108:104753] current thread<NSThread: 0x1001052f0>{number = 1, name = main}
// 2016-07-04 15:05:02.276 多线程Demo[2108:104785] download image2 <NSThread: 0x1005004d0>{number = 2, name = (null)}
// 2016-07-04 15:05:02.276 多线程Demo[2108:104788] download image3 <NSThread: 0x100500e70>{number = 3, name = (null)}
// 2016-07-04 15:05:02.276 多线程Demo[2108:104787] download image1 <NSThread: 0x100701a20>{number = 4, name = (null)}
总结:只有异步操作才能够创建新的线程,同步操作不会创建新的线程(主线程这里除外)
NSOperation/NSOperationQueue:
NSOperation/NSOperationQueue是苹果公司对GCD的封装,完全的面向对象,让开发者使用起来更加方便,对于他的理解NSOperation类似GCD中的任务,NSOperationQueue类似GCD中的队列,好了具体操作看一下代码实现。
最后:文章可能存在错别字或者理解不到位的地方,欢迎挑刺,如果你也是一枚IOS爱好者,请加入我们的QQ群:126440594。