2019-11-21iOS多线程之GCD(四)

今天主要讲下dispatch_barrier_async、dispatch_after、dispatch_once

1、dispatch_barrier_async   顾名思义,barrier有栅栏、阻碍、分界线的意思。dispatch_barrier_async函数允许你在一个并发队列上创建一个同步点。当并发队列在执行过程中遇到这个barrier,并发队列会延迟执行,不会继续往下执行,直到barrier之前的并发操作全部完成。使用该函数需要注意,队列必须是自己创建的并发队列,不能是串行队列或全局的并发队列,否则效果和dispatch_async一样。示例代码如下:

    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(concurrentQueue, ^{

        NSLog(@" task1 begin");

        [NSThread sleepForTimeInterval:2];

        NSLog(@" task1 end");

    });

    dispatch_async(concurrentQueue, ^{

        NSLog(@" task2 begin");

        [NSThread sleepForTimeInterval:5];

        NSLog(@" task2 end");

    });

    //加上栅栏,堵住了并发队列的异步操作。下面的操作不会执行,直到栅栏以上的代码执行完成。不加栅栏,task3会立即执行

    dispatch_barrier_async(concurrentQueue, ^{

        NSLog(@"在这里插入了一段代码,等待上面的任务执行结束再执行,包括下面的task3");

    });

    dispatch_async(concurrentQueue, ^{

        NSLog(@" task3 begin");

        NSLog(@" task3 end");

    });

2、dispatch_after  这个是用的最频繁的一个GCD函数了,可以在指定时间后向指定队列插入任务。注意:这不是在指定时间后再执行,而是把任务指定时间插到指定队列执行.奇怪的是,如果把dispatch_after要执行的任务加到并发队列中的话,会新产生一个线程,和并发队列的线程不是同一个线程,并且dispatch_after插入的任务会在放进队列后立即执行(因为是新起了一个线程)。如果是串行队列的话,则是原来的意思:在指定时间后向指定队列插入任务。如果此时队列中没有资源的话,dispatch_after的任务就不会立即执行。示例代码:

    //注意这里的队列类型

    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(concurrentQueue, ^{

        NSLog(@"begin in %@",NSThread.currentThread);

        [NSThread sleepForTimeInterval:5];

        NSLog(@"end in %@",NSThread.currentThread);


    });

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)), concurrentQueue, ^{

        NSLog(@"i am a hero in %@",NSThread.currentThread);

    });

3、dispatch_once  该函数是保证在APP生命周期内,执行的任务只会被执行一次,并且是线程安全的,通常用来创建单例对象(比synchronized方法要有更高的性能)。示例代码如下:

+(instancetype)sharedInstance{

    static   MyClass *instance =nil;

    static  dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        instance = [[MyClass alloc]init];

    });

    return instance;

}

你可能感兴趣的:(2019-11-21iOS多线程之GCD(四))