• iOS 多线程的简单理解(2) 队列 :串行 ,并行,MainQueue,GlobalQueue


    多线程队列是装载线程任务的队形结构。(系统以先进先出的方式调度队列中的任务执行 FIFO)。在GCD中有两种队列:

    串行队列、并发队列。

    队列 :串行队列、并发队列,全局主对列,全局并发队列

    2.1.  串行队列:线程只能依次有序的执行。

    2.1.1 串行方法 1

    - (void)SerialQueueOne{
         
        NSLog(@"串行1 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
        
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"串行1   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        dispatch_sync(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"串行1   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        NSLog(@"串行1 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 13:49:47.427330+0800 DeadThread[8972:2450330] 串行1 start :::<NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427470+0800 DeadThread[8972:2450330] 串行1   index 0 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427567+0800 DeadThread[8972:2450330] 串行1   index 1 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427636+0800 DeadThread[8972:2450330] 串行1   index 2 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427696+0800 DeadThread[8972:2450330] 串行1   index 10 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427819+0800 DeadThread[8972:2450330] 串行1   index 11 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427893+0800 DeadThread[8972:2450330] 串行1   index 12 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427966+0800 DeadThread[8972:2450330] 串行1 end :::<NSThread: 0x60800006ae80>{number = 1, name = main}
    

     得到结果:::

     1.代码顺序 执行;

    2.1.2 串行方法 2

    - (void)SerialQueueTwo{
        
        NSLog(@"串行2 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
        
       dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"串行2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"串行2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
    
           NSLog(@"串行2 end :::%@",[NSThread currentThread]); 
    }
    

     执行结果:::

    2017-12-20 13:50:47.130380+0800 DeadThread[8993:2458517] 串行1 start :::<NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130533+0800 DeadThread[8993:2458517] 串行1   index 0 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130648+0800 DeadThread[8993:2458517] 串行1   index 1 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130724+0800 DeadThread[8993:2458517] 串行1   index 2 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130896+0800 DeadThread[8993:2458517] 串行1   index 10 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130979+0800 DeadThread[8993:2458517] 串行1   index 11 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.131057+0800 DeadThread[8993:2458517] 串行1   index 12 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.131130+0800 DeadThread[8993:2458517] 串行1 end :::<NSThread: 0x60c000071300>{number = 1, name = main}
    

     得到结果:::

    1.没有开启线程

    2.代码顺序执行;

    2.2 并发队列:线程可以同时一起进行执行。实际上是CPU在多条线程之间快速的切换。(并发功能只有在异步(dispatch_async)函数下才有效)

    2.2.1 并发方法 1

    - (void)concurrentQueueOne{
        
        NSLog(@"并发1 start :::%@",[NSThread currentThread]);
    
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"并发1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_sync(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"并发1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"并发1 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 13:52:37.606997+0800 DeadThread[9023:2470506] 并发1 start :::<NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607130+0800 DeadThread[9023:2470506] 并发1  index 0 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607197+0800 DeadThread[9023:2470506] 并发1  index 1 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607447+0800 DeadThread[9023:2470506] 并发1  index 2 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607685+0800 DeadThread[9023:2470506] 并发1  index 10 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607891+0800 DeadThread[9023:2470506] 并发1  index 11 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.608056+0800 DeadThread[9023:2470506] 并发1  index 12 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.608190+0800 DeadThread[9023:2470506] 并发1 end :::<NSThread: 0x608000261600>{number = 1, name = main}
    

     得到结果:::

    1.线程顺序执行

    2.2.2 并发方法 2

    - (void)concurrentQueueTwo{
        
        NSLog(@"并发2 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"并发2  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_async(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"并发2  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"并发2 end :::%@",[NSThread currentThread]);
    }
    

     执行结果::;

    2017-12-20 13:56:45.573695+0800 DeadThread[9084:2492640] 并发2 start :::<NSThread: 0x604000077d80>{number = 1, name = main}
    2017-12-20 13:56:45.573891+0800 DeadThread[9084:2492640] 并发2 end :::<NSThread: 0x604000077d80>{number = 1, name = main}
    2017-12-20 13:56:45.573907+0800 DeadThread[9084:2492674] 并发2  index 0 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
    2017-12-20 13:56:45.573908+0800 DeadThread[9084:2492675] 并发2  index 10 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
    2017-12-20 13:56:45.574283+0800 DeadThread[9084:2492674] 并发2  index 1 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
    2017-12-20 13:56:45.574344+0800 DeadThread[9084:2492675] 并发2  index 11 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
    2017-12-20 13:56:45.574420+0800 DeadThread[9084:2492675] 并发2  index 12 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
    2017-12-20 13:56:45.574422+0800 DeadThread[9084:2492674] 并发2  index 2 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
    

     得到结果:::

    1.添加两个 任务代码块,开启两个线程;

    2.子线程中代码 不是按顺序执行

    2.3 全局主队列::::

    2.3.1  主队列 同步 死锁

    - (void)syncMain {
     
        NSLog(@"
    
    **************主队列同步,放到主线程会死锁***************
    
    ");
     
        // 主队列
        dispatch_queue_t queue = dispatch_get_main_queue();
     
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列同步1   %@",[NSThread currentThread]);
            }
        });
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列同步2   %@",[NSThread currentThread]);
            }
        });
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列同步3   %@",[NSThread currentThread]);
            }
        });
    }
    

     死锁原因:::

        如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。
    
        而同步对于任务是立刻执行的,那么当把第一个任务放进主队列时,它就会立马执行。
    
        可是主线程现在正在处理syncMain方法,任务需要等syncMain执行完才能执行。
    
        syncMain执行到第一个任务的时候,又要等第一个任务执行完才能往下执行第二个和第三个任务。
    
        这样syncMain方法和第一个任务就开始了互相等待,形成了死锁。
    

    2.3.2  主队列 异步

    - (void)asyncMain {
     
        NSLog(@"**************主队列异步***************");
     
        // 主队列
        dispatch_queue_t queue = dispatch_get_main_queue();
     
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列异步1   %@",[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列异步2   %@",[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列异步3   %@",[NSThread currentThread]);
            }
        });
    }
    

     执行结果:::

    2017-12-20 14:20:01.729412+0800 DeadThread[9257:2636939] **************主队列异步***************
    2017-12-20 14:20:01.732208+0800 DeadThread[9257:2636939] 主队列异步1   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732326+0800 DeadThread[9257:2636939] 主队列异步1   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732456+0800 DeadThread[9257:2636939] 主队列异步1   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732726+0800 DeadThread[9257:2636939] 主队列异步2   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732931+0800 DeadThread[9257:2636939] 主队列异步2   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733026+0800 DeadThread[9257:2636939] 主队列异步2   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733128+0800 DeadThread[9257:2636939] 主队列异步3   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733251+0800 DeadThread[9257:2636939] 主队列异步3   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733502+0800 DeadThread[9257:2636939] 主队列异步3   <NSThread: 0x604000261080>{number = 1, name = main}
    

    得到结果:::

    1. 主队列是个同步队列

    2.4 全局并发队列

    2.4.1

    - (void)globalQueueOne{
        
        NSLog(@"global1 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
        
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"global1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_sync(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"global1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"global1 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 14:27:02.302953+0800 DeadThread[9352:2669397] global1 start :::<NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303132+0800 DeadThread[9352:2669397] global1  index 0 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303230+0800 DeadThread[9352:2669397] global1  index 1 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303322+0800 DeadThread[9352:2669397] global1  index 2 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303397+0800 DeadThread[9352:2669397] global1  index 10 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303467+0800 DeadThread[9352:2669397] global1  index 11 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303557+0800 DeadThread[9352:2669397] global1  index 12 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303638+0800 DeadThread[9352:2669397] global1 end :::<NSThread: 0x6000000655c0>{number = 1, name = main}
    

    2.4.2

    - (void)globalQueueTwo{
        
        NSLog(@"global2 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"global2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_async(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"global2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"global2 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 14:28:27.498062+0800 DeadThread[9382:2678820] global2 start :::<NSThread: 0x600000076700>{number = 1, name = main}
    2017-12-20 14:28:27.498208+0800 DeadThread[9382:2678820] global2 end :::<NSThread: 0x600000076700>{number = 1, name = main}
    2017-12-20 14:28:27.498250+0800 DeadThread[9382:2679707] global2   index 0 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
    2017-12-20 14:28:27.498260+0800 DeadThread[9382:2679706] global2   index 10 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
    2017-12-20 14:28:27.498555+0800 DeadThread[9382:2679707] global2   index 1 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
    2017-12-20 14:28:27.498692+0800 DeadThread[9382:2679706] global2   index 11 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
    2017-12-20 14:28:27.498710+0800 DeadThread[9382:2679707] global2   index 2 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
    2017-12-20 14:28:27.498753+0800 DeadThread[9382:2679706] global2   index 12 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
    
  • 相关阅读:
    情态动词
    形容词
    时态
    介词和介词短语
    句子成分
    被动语态
    C# Task使用CancellationTokenSource取消任务
    EntityFramework Core 迁移忽略主外键关系
    获取项目程序集,排除所有的系统程序集(Microsoft.***、System.***等)、Nuget下载包
    .NET使用StackExchange.Redis
  • 原文地址:https://www.cnblogs.com/Bob-blogs/p/8073578.html
Copyright © 2020-2023  润新知