美文网首页
IOS多线程

IOS多线程

作者: 暗香有独 | 来源:发表于2016-07-08 10:50 被阅读15次
    什么是多线程:

    什么是进程 ?

    想说清什么是多线程,我们还需要了解一些其他的东西,什么是进程,网上大多数资料解释是一个运行中的应用程序,举个例子,比如电脑上运行的QQ,微信。。。是不是感觉有点抽象,这样去想,不管是QQ还是微信他们只是一个应用程序,应用程序运行需要内存存储一些东西,比如变量常量方法函数。。。这些东西运行需要执行顺序和计算,然后根据我们编程逻辑在屏幕上显示出我们所想要的东西,计算机上有若干个应用程序,我们不能任由他们在内存或CPU上乱搞吧,这样不就混乱了,因此程序在运行时会创建一个属于自己的空间,在这个空间里做自己想要做的事情,那么这个空间就是我们要说的进程。

    __ 什么是线程 ?__

    说了这么多,可能有人会问这和多线程有毛关系,再说这个毛关系之前我们先理清什么是线程,网上大多数资料的解释是把一堆要执行的指令串联起来称为线程,这又是什么鬼东西,好了这确实不是什么鬼东西,说清楚就好了,举个QQ登录的例子,我们一般打开QQ登录进入之后才能看到我们的好友,这句话我们分析下是怎么回事,我们要看到我们的QQ好友,那么我们必须输入账号密码,再去点击登录按钮,然后我们就看到我们的QQ好友了,是不是这些操作就像一条线一样贯穿我们最终看到QQ好友,明白线程了吧。

    什么是多线程 ?

    我们再来看看多线程,网上解释是同一时刻有多条线程执行我们称为多线程,说到这里有人又开始糊涂了,CPU不是一个核心吗,一次只能执行一条线程,怎么突然又跑出多个线程来,不符合科学呀,不要激动,我解释下,首先我肯定一点你所说的是正确的,看来你对CPU的执行还算了解,其实说到底CPU同时还是在执行一个线程,那又是怎么同时执行多条线程了,他会把多个线程切分成小块,因为运行速度特别快,他每秒可能从多个线程中个取出一块来执行,造成我们视觉的效果就是同一时刻就好像有多条线程在执行。

    IOS中的多线程#####

    IOS中常用到的多线程处理有三个:

    1. NSThread
    2. GCD
    3. NSOperation/NSOperationQueue

    NSThread:

    GCD:
    GCD是苹果多核编程处理的解决方案,底层通过纯C语言实现。在开始学习GCD时首先必须了解几个概念:
    1.任务:做什么操作,实现什么功能。
    1.1 同步操作:多个任务执行中,会阻碍下一个任务执行,直到第一个任务执行完成,才会执行下一个任务。
    1.2 异步操作:多个任务执行中,相互不受影响,各执行个的任务。
    2.队列:将定义的任务存放起来。
    2.1 串行队列:队列中的任务执行通道只有一条,同一时刻只会执行一个任务。
    2.2 并行队列:队列中的任物执行通道有多条,同一时刻会执行多个任务。

    Paste_Image.png

    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

    相关文章

      网友评论

          本文标题:IOS多线程

          本文链接:https://www.haomeiwen.com/subject/lzwxjttx.html