多线程 同步&异步

2023-06-14  本文已影响0人  xxttw

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

同步异步
队列类型
容易混淆的术语 同步 异步 并发 串行
多线程面试题
- (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
     */
}
上一篇下一篇

猜你喜欢

热点阅读