iOS多线程概括

pthread

 

NSThread

 

NSOperation

 

GCD

    一.并行队列

    1.向并行队列提交同步任务,(根据显示结果可知:全部任务所有在主线程执行,全部任务都是按顺序执行的)html

//线程与线程之间的执行速度多是不肯定的
    //1. 建立一个并行队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

        //并行队列中提交多个异步任务,任务的顺序不能肯定
        //同步提交任务任务的顺序能够肯定
        dispatch_sync(concurrentQueue, ^{
            
            if ([NSThread isMainThread]) {
                NSLog(@"主线程");
            }else{
                NSLog(@"非主线程");
            }
            
            for (int i = 0; i < 100; i++) {
                NSLog(@"任务一:%d", i);
            }
        });
        NSLog(@"---1---");
        dispatch_sync(concurrentQueue, ^{
            if ([NSThread isMainThread]) {
                NSLog(@"主线程");
            }else{
                NSLog(@"非主线程");
            }

            for (int i = 0; i < 100; i++) {
                NSLog(@"任务二:%d", i);
            }
        });
        NSLog(@"---2---");
        dispatch_sync(concurrentQueue, ^{
            if ([NSThread isMainThread]) {
                NSLog(@"主线程");
            }else{
                NSLog(@"非主线程");
            }

            for (int i = 0; i < 100; i++) {
                NSLog(@"任务三:%d", i);
            }
        });
         NSLog(@"---3---");

    2.向并行队列提交异步任务(根据结果:全部任务都是在非主线程中执行的,并且任务执行的顺序是不肯定的)编程

//并行队列中提交多个异步任务,任务的顺序不能肯定
    dispatch_async(concurrentQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务一:%d", i);
        }
    });
    NSLog(@"---1---");
    dispatch_async(concurrentQueue, ^{
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务二:%d", i);
        }
    });
    NSLog(@"---2---");
    dispatch_async(concurrentQueue, ^{
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务三:%d", i);
        }
    });
    NSLog(@"---3---");

     

    二.串行队列

   1.向串行队列同步提交任务(从结果可知:全部任务都在主线程中执行,全部任务都是按顺序执行的)数据结构

//1. 建立串行队列,一个串行队列对应一个线程
    //1.1. 第一个参数是队列的名称
    //1.2. 第二个参数是队列的类型,NULL表示串行队列
    dispatch_queue_t serialQueue = dispatch_queue_create("com.serialQueue", DISPATCH_QUEUE_SERIAL);
    //2. 若是任务在不一样的线程中执行,那么它们的执行顺序是不肯定的
    dispatch_sync(serialQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务一:%d", i);
        }
    });
    
    NSLog(@"---1---");
    dispatch_sync(serialQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
            for (int i = 0; i < 100; i++) {
                NSLog(@"任务二:%d", i);
            }
    });
        
        NSLog(@"---2---");
        dispatch_sync(serialQueue, ^{
            
            if ([NSThread isMainThread]) {
                NSLog(@"主线程");
            }else{
                NSLog(@"非主线程");
            }
                for (int i = 0; i < 100; i++) {
                    NSLog(@"任务三:%d", i);
                }
            });
            NSLog(@"---3---");

  2.向串行队列提交异步任务(从结果可知:全部的任务都是在非主线程中执行的,全部的任务都是按顺序执行的)并发

dispatch_async(serialQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务一:%d", i);
        }
    });
    
    NSLog(@"---1---");
    dispatch_async(serialQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务二:%d", i);
        }
    });
    NSLog(@"---2---");
    dispatch_async(serialQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }
        for (int i = 0; i < 100; i++) {
            NSLog(@"任务三:%d", i);
        }
    });
    NSLog(@"---3---");

结果对比:异步

  

 

总结:

1.不论是串行队列仍是并行队列,同步提交任务都是在主线程中执行的,异步提交任务都是在非主线程中执行的(这里相对于3.4来说的)async

2.并行队列的任务,若是不在同一线程,能够与主线程同时执行,主线程中的任务优先其余线程的任务执行,但不排除其余线程的任务和主线程的任务同时间进行函数

3.同步提交任务,任务所在的线程与提交任务所在的线程是同样的优化

4.异步提交任务,任务所在的线程与提交任务所在的线程是不同的spa

5.同一线程,全部任务都是先进先出按顺序来的(串行同步,并行同步都在主线程)线程

6.串行异步,任务在同一个线程,任务所在的线程与提交任务所在的线程是不同的(因此出现任务一和主线程的任务先执行,任务二和任务三后执行,由于任务一二三在同一个线程)

7.并行异步,任务在不一样线程,任务所在的线程与提交任务所在的线程是不同的(因此出现任务和主线程的任务都是同时执行)

因此根据上面的总结能够体会到,任务的执行顺序和会不会阻塞,我门只须要判断清楚任务所在的线程就能够了,不一样线程能够同时执行,同一线程只能按顺序执行

最后只需记住多个任务同时执行用: 并行异步  两个任务同时执行用:串行异步  全部任务按前后顺序执行 :串行同步,并行同步  可是这里只是相对于一个线程编程的时候,好比主线程,若是在主线程里面建立一个其余的线程,而后同步提交任务,咱们是否是也能够实现两个甚至是多个任务同时运行了,这个还有待验证

 

    三.界面假死与死锁

    概念这里参考 http://www.mamicode.com/info-detail-1010323.html 为了避免麻烦就直接复制粘贴了

  首先明确一下“同步&异步”“串行&并发”这两组基本概念:

同步执行:好比这里的dispatch_sync,这个函数会把一个block加入到指定的队列中,并且会一直等到执行完blcok,这个函数才返回。所以在block执行完以前,调用dispatch_sync方法的线程是阻塞的。

与之对应的就有“异步执行”的概念:

异步执行:通常使用dispatch_async,这个函数也会把一个block加入到指定的队列中,可是和同步执行不一样的是,这个函数把block加入队列后不等block的执行就马上返回了。

接下来看一看另外一组相对的概念:“串行&并发”

串行队列:好比这里的dispatch_get_main_queue。这个队列中全部任务,必定按照先来后到的顺序执行。不只如此,还能够保 证在执行某个任务时,在它前面进入队列的全部任务确定执行完了。对于每个不一样的串行队列,系统会为这个队列创建惟一的线程来执行代码。

与之相对的是并发队列:

并发队列:好比使用dispatch_get_global_queue。这个队列中的任务也是按照先来后到的顺序开始执行,注意是开始,可是它们的执行结束时间是不肯定的,取决于每一个任务的耗时。对于n个并发队列,GCD不会建立对应的n个线程而是进行适当的优化

    总结一下,到底什么是死锁。首先,虽然刚刚咱们提到了队列和线程,以及它们之间的对应关系,可是死锁必定是针对线程 而言的,队列只是GCD给出的抽象数据结构。所谓的死锁,必定是发生在一个或多个线程之间的。那么死锁和线程阻塞的关系呢,能够这么理解,双向的阻塞致使 了死锁。由于阻塞是线程中常常发生的事情,最多就是主线程的阻塞影响了用户体验。而一旦出现了双向的阻塞,就致使了死锁。咱们能够看到,主线程是串行的, 在执行某一个任务的时候线程被阻塞了,而这个任务(dispatch_sync)在执行时,又要求阻塞主线程,从而致使了互相的阻塞,也就是死锁

分析:若是阻塞时间过长久会造成“界面假死”,若是双向阻塞就会造成死锁,这两种状况的造成咱们就不考虑异步提交了,由于异步提交是根本不会造成阻塞,因此咱们只看同步提交的状况

  //1. 主队列里的任务必定在主线程上执行
    //2. 不该该在主线程中执行耗时的任务,不然会致使主线程阻塞,从而使界面“假死”
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t serialQueue = dispatch_queue_create("com.serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    
    dispatch_sync(concurrentQueue, ^{
        
        if ([NSThread isMainThread]) {
            NSLog(@"主线程");
        }else{
            NSLog(@"非主线程");
        }

        //获取当前时间,秒钟
        CFAbsoluteTime begin = CFAbsoluteTimeGetCurrent();
        
        //整个管理文件或者文件夹
        [[NSFileManager defaultManager] copyItemAtPath:@"/Users/zhouzhi/百度云同步盘/电子专业书籍" toPath:@"/Users/zhouzhi/Desktop/电子书" error:nil];
        
        //获取结束时间点
        CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
        //打印消耗的时间
        NSLog(@"%.2f秒", end - begin);
    });
    NSLog(@"任务执行完成了");

 结果分析:

 

    除了同步提交任务到mainQueue会造成死锁,其余都是界面假死:说明只有同步向当前对列提交任务才会形成死锁

相关文章
相关标签/搜索