iOS多线程:GCD详解

参考链接:

iOS 多线程:『GCD』详尽总结

1.对参考链接中4.5.2的补充

1.1 同步执行dispatch_sync,必须上一个执行完再执行下一个,不管这两个任务所属队列和所在线程是否相同

从下面的测试结果可以看出:同步执行任务,任务会按添加代码的先后顺序执行,写在前面的任务先执行,写在后面的任务后执行. 如“12—%@”虽然是在子线程里执行的,但是一定要等到主线程中的“1—%@”,“2—%@”执行完后再执行


- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"调用前---%@",[NSThread currentThread]);  // 打印当前线程
     
    [NSThread detachNewThreadSelector:@selector(syncSerial) toTarget:self withObject:nil];
    
     [NSThread sleepForTimeInterval:1];
    NSLog(@"调用后---%@",[NSThread currentThread]);  // 打印当前线程
     [NSThread sleepForTimeInterval:8];
   NSLog(@"调用后1---%@",[NSThread currentThread]);
    // Do any additional setup after loading the view.
}

- (void)syncSerial {
    NSLog(@"syncSerial---begin---%@",[NSThread currentThread]);  // 打印当前线程
    
    
   dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_queue_t queue1 = dispatch_queue_create("net.bujige.testQueu", DISPATCH_QUEUE_SERIAL);
     dispatch_queue_t queue2 = dispatch_queue_create("net.bujige.testQue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue1, ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
            NSLog(@"11---%@",[NSThread currentThread]);      // 打印当前线程
        });
       
      
        NSLog(@"queue1后---%@",[NSThread currentThread]);  // 打印当前线程
    
    dispatch_sync(queue, ^{
        // 追加任务 1
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
   
    
    dispatch_sync(queue, ^{
        // 追加任务 2
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
    
    dispatch_sync(queue1, ^{
        // 追加任务 2
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"12---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
    
    dispatch_sync(queue2, ^{
        // 追加任务 2
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"222---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
     NSLog(@"queue2后---%@",[NSThread currentThread]);
    
    dispatch_sync(queue, ^{
        // 追加任务 3
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
  
     NSLog(@"syncSerial---end---%@",[NSThread currentThread]);  // 打印当前线程
}

打印结果:

2020-04-23 16:37:32.310662+0800 oc-interview[2995:87379] 调用前---<NSThread: 0x6000028e5d80>{number = 1, name = main}
2020-04-23 16:37:32.311043+0800 oc-interview[2995:87488] syncSerial---begin---<NSThread: 0x6000028bba80>{number = 6, name = (null)}
2020-04-23 16:37:33.312025+0800 oc-interview[2995:87379] 调用后---<NSThread: 0x6000028e5d80>{number = 1, name = main}
2020-04-23 16:37:33.312097+0800 oc-interview[2995:87488] 11---<NSThread: 0x6000028bba80>{number = 6, name = (null)}
2020-04-23 16:37:33.312446+0800 oc-interview[2995:87488] queue1后---<NSThread: 0x6000028bba80>{number = 6, name = (null)}
2020-04-23 16:37:37.313452+0800 oc-interview[2995:87379] 调用后1---<NSThread: 0x6000028e5d80>{number = 1, name = main}
2020-04-23 16:37:38.331959+0800 oc-interview[2995:87379] 1---<NSThread: 0x6000028e5d80>{number = 1, name = main}
2020-04-23 16:37:39.345965+0800 oc-interview[2995:87379] 2---<NSThread: 0x6000028e5d80>{number = 1, name = main}
2020-04-23 16:37:40.349866+0800 oc-interview[2995:87488] 12---<NSThread: 0x6000028bba80>{number = 6, name = (null)}
2020-04-23 16:37:41.354956+0800 oc-interview[2995:87488] 222---<NSThread: 0x6000028bba80>{number = 6, name = (null)}
2020-04-23 16:37:41.355392+0800 oc-interview[2995:87488] queue2后---<NSThread: 0x6000028bba80>{number = 6, name = (null)}
2020-04-23 16:37:42.356360+0800 oc-interview[2995:87379] 3---<NSThread: 0x6000028e5d80>{number = 1, name = main}
2020-04-23 16:37:42.356839+0800 oc-interview[2995:87488] syncSerial---end---<NSThread: 0x6000028bba80>{number = 6, name = (null)}

1.2 异步执行任务

1.2.1 后面的任务不需要等它,但它还是需要等前面的执行完

只把1.1代码中的“12—”前的dispatch_sync改为 dispatch_async后得到的打印结果,"12—"不会阻碍“222—”的运行,它新开了线程
在这里插入图片描述

1.2.2 如下图主队列中的3还是要等到1,2执行完了它才执行。1,2,3

下图在1.1代码的基础上,把三个红圈的地方改成了异步执行后的运行结果

在这里插入图片描述

2.串行队列异步执行,会新开一条线程。并行队列异步执行会新开多条线程(如下演示)

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"调用前---%@",[NSThread currentThread]);  // 打印当前线程
     
    [NSThread detachNewThreadSelector:@selector(syncSerial) toTarget:self withObject:nil];
    
     [NSThread sleepForTimeInterval:1];
    NSLog(@"调用后---%@",[NSThread currentThread]);  // 打印当前线程
     [NSThread sleepForTimeInterval:8];
   NSLog(@"调用后1---%@",[NSThread currentThread]);
    // Do any additional setup after loading the view.
}

- (void)syncSerial {
    NSLog(@"syncSerial---begin---%@",[NSThread currentThread]);  // 打印当前线程
    
    
   dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_queue_t queue1 = dispatch_queue_create("net.bujige.testQueu", DISPATCH_QUEUE_SERIAL);
     dispatch_queue_t queue2 = dispatch_queue_create("net.bujige.testQue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue1, ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
            NSLog(@"11---%@",[NSThread currentThread]);      // 打印当前线程
        });
       
      
        NSLog(@"queue1后---%@",[NSThread currentThread]);  // 打印当前线程
    
    dispatch_async(queue1, ^{
        // 追加任务 1
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"12---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
   
    
    dispatch_async(queue1, ^{
        // 追加任务 2
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"13---%@",[NSThread currentThread]);      // 打印当前线程
    });
    
    
    dispatch_async(queue2, ^{
        // 追加任务 2
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"221---%@",[NSThread currentThread]);      // 打印当前线程
    });


    dispatch_async(queue2, ^{
        // 追加任务 2
        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
        NSLog(@"222---%@",[NSThread currentThread]);      // 打印当前线程
    });

     NSLog(@"queue2后---%@",[NSThread currentThread]);
//
//    dispatch_sync(queue, ^{
//        // 追加任务 3
//        [NSThread sleepForTimeInterval:1];              // 模拟耗时操作
//        NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
//    });
    
  
     NSLog(@"syncSerial---end---%@",[NSThread currentThread]);  // 打印当前线程
}
2020-04-23 18:19:18.891868+0800 oc-interview[4000:124178] 调用前---<NSThread: 0x600000462d00>{number = 1, name = main}
2020-04-23 18:19:18.892303+0800 oc-interview[4000:124286] syncSerial---begin---<NSThread: 0x600000401900>{number = 7, name = (null)}
2020-04-23 18:19:18.892851+0800 oc-interview[4000:124286] queue1后---<NSThread: 0x600000401900>{number = 7, name = (null)}
2020-04-23 18:19:18.893222+0800 oc-interview[4000:124286] queue2后---<NSThread: 0x600000401900>{number = 7, name = (null)}
2020-04-23 18:19:18.893576+0800 oc-interview[4000:124286] syncSerial---end---<NSThread: 0x600000401900>{number = 7, name = (null)}
2020-04-23 18:19:19.892995+0800 oc-interview[4000:124178] 调用后---<NSThread: 0x600000462d00>{number = 1, name = main}
2020-04-23 18:19:19.897289+0800 oc-interview[4000:124277] 11---<NSThread: 0x60000043bf80>{number = 5, name = (null)}
2020-04-23 18:19:19.897293+0800 oc-interview[4000:124276] 221---<NSThread: 0x60000043d7c0>{number = 6, name = (null)}
2020-04-23 18:19:19.897298+0800 oc-interview[4000:124279] 222---<NSThread: 0x600000401840>{number = 8, name = (null)}
2020-04-23 18:19:20.901891+0800 oc-interview[4000:124277] 12---<NSThread: 0x60000043bf80>{number = 5, name = (null)}
2020-04-23 18:19:21.906531+0800 oc-interview[4000:124277] 13---<NSThread: 0x60000043bf80>{number = 5, name = (null)}
2020-04-23 18:19:27.894360+0800 oc-interview[4000:124178] 调用后1---<NSThread: 0x600000462d00>{number = 1, name = main}
发布了161 篇原创文章 · 获赞 70 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/baidu_40537062/article/details/105711345