美文网首页
多线程 同步&异步

多线程 同步&异步

作者: xxttw | 来源:发表于2023-06-14 20:40 被阅读0次

    image.png
    • 同步函数dispatch_sync :
    1. 阻塞当前线程,直到当前添加到队列的任务执⾏完毕
    2. 只能在当前线程执⾏任务,不具备开启新线程的能⼒。
    • 异步函数dispatch_async:
    1. 不会阻塞当前线程,不需要等待,任务可以继续执⾏;
    2. 可以在新的线程执⾏任务,具备开启新线程的能⼒。(并发队列可以开启多条⼦线程,串⾏队列只能开启⼀条⼦线程

    同步异步
    • dispatch_sync() 在当前线程, 以同步的方式立刻执行任务

    • dispatch_async() 具备开起新线程的能力, 以异步的方式执行任务, 不会阻塞其他线程

    队列类型
    • 并发队列 Concurrent
      可以让多个任务并发(同时)执行
    • 串行队列 Serial
      让任务一个接着一个的执行(一个任务执行完毕后, 才能执行下一个任务)
    容易混淆的术语 同步 异步 并发 串行
    • 同步和异步的主要区别: 是否能开启新的线程
      同步: 在当前线程中执行任务, 不具备开启新线程的能力
      异步: 在新的线程中执行任务, 具备开启新线程的能力

    • 并发和串行主要影响: 任务执行的方式
      并发: 多个任务并发(同时)执行
      串行: 一个任务执行完毕后 再执行下一个任务

    多线程面试题
    - (void)interview1
    {
        
        // 以下代码, 会有什么问题
        NSLog(@"任务1-%@", [NSThread currentThread]);
        dispatch_queue_t queue = dispatch_get_main_queue();
        
        dispatch_sync(queue, ^{
            NSLog(@"任务2-%@", [NSThread currentThread]);
    
        });
        NSLog(@"任务3-%@", [NSThread currentThread]);
        /*
         首先任务1会打印
         我们获取到一个主队列, 以同步的方式在主队列里添加了任务, sync会立刻在当前线程执行该任务, 因为是串行队列会阻塞当前线程
         但是interview1这个任务也在主线程中执行, 任务2必须等待它执行完毕后才能执行, 但是interview1要执行完毕,
         又要等到任务2执行完毕后,它才能继续执行,所以就产生了死锁, 解决方案是以async的方式添加,这样就会新开启一条线程执行任务2,
         
         */
        
    }
    
    - (void)interview2
    {
        NSLog(@"任务1-%@", [NSThread currentThread]);
        dispatch_queue_t queue = dispatch_get_main_queue();
        
        dispatch_async(queue, ^{
            NSLog(@"任务2-%@", [NSThread currentThread]);
    
        });
        NSLog(@"任务3-%@", [NSThread currentThread]);
        /*
         dispatch_async以异步方式执行任务, 因为是主队列,不会开启新的线程, 还是以串行的方式执行,
         任务3不会阻塞当前线程
         打印结果 任务1 任务3 任务2
         */
    }
    
    - (void)interview3
    {
        
        // 以下代码在主线程执行, 会不会产生死锁? 会
        NSLog(@"任务1----%@", [NSThread currentThread]);
        dispatch_queue_t queue = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
    
        dispatch_async(queue, ^{ // block0
            NSLog(@"任务2----%@", [NSThread currentThread]);
            dispatch_sync(queue, ^{ //block1
                NSLog(@"任务3----%@", [NSThread currentThread]);
            });
            NSLog(@"任务4----%@", [NSThread currentThread]);
    
        });
        NSLog(@"任务5----%@", [NSThread currentThread]);
        
        /*
         首先创建的是一条串行队列, 以异步的方式添加任务到队列中, 在以同步的方式添加任务到队列中,同步任务会立刻在当前线程执行任务,并阻塞当前线程
         但是当前队列是串行队列, block0这个任务还未执行完毕, block1需要等到block0执行完毕后才能继续执行,
         但是block0 又要等待block1执行完毕后 才能继续执行, 两个任务互相等待, 产生了死锁. 解决防范是block1 以async的方式执行任务,
         */
    }
    
    - (void)interview4
    {
        
        // 以下代码在主线程执行, 会不会产生死锁? 不会
        NSLog(@"任务1----%@", [NSThread currentThread]);
        dispatch_queue_t queue = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
        dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_async(queue, ^{
            NSLog(@"任务2----%@", [NSThread currentThread]);
            // 虽然是同步执行,要求立刻执行,但是queue和queue2 并不是一个队列,所以不会互相等待,
            dispatch_sync(queue2, ^{
                NSLog(@"任务3----%@", [NSThread currentThread]);
            });
            NSLog(@"任务4----%@", [NSThread currentThread]);
    
        });
        NSLog(@"任务5----%@", [NSThread currentThread]);
        /*
         队列1是串行队列, 队列2是并发队列, 首先异步的方式添加任务2到串行队列中, 在以同步的方式添加任务3到并发队列中,会立刻执行
         任务3虽然是以同步的方式添加到队列,但是queue1和queue2不在一个队列中, 不会产生互相等待的情况, 所以不会产生死锁
         打印顺序是 任务1 -> 任务5 -> 任务2 -> 任务3 > 任务4
         */
    }
    - (void)interview5
    {
        
        // 以下代码在主线程执行, 会不会产生死锁? 不会
        NSLog(@"任务1----%@", [NSThread currentThread]);
        dispatch_queue_t queue = dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_async(queue, ^{
            NSLog(@"任务2----%@", [NSThread currentThread]);
            
            dispatch_sync(queue, ^{
                NSLog(@"任务3----%@", [NSThread currentThread]);
            });
            NSLog(@"任务4----%@", [NSThread currentThread]);
    
        });
        NSLog(@"任务5----%@", [NSThread currentThread]);
        
        /*
        创建的并发队列, 异步的方式添加任务2到队列中, 再已同步的方式添加任务3到队列中, 任务3会立刻执行
        因为是并发队列, 可以多个任务同时执行, 不会阻塞队列
        打印结果是 任务1 -> 任务5 -> 任务2 -> 任务3 -> 任务4
         */
    }
    

    相关文章

      网友评论

          本文标题:多线程 同步&异步

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