iOS面试题

iOS 同步 异步 栅栏函数的区别

2019-10-11  本文已影响0人  萨缪

dispatch_barrier_async

场景需求:需要异步完成三个任务。任务一、任务二、任务三。要求:任务三必须在任务一、任务二完成之后触发。这就需要使用dispatch_barrier_async。
特点:像一堵围墙、成为任务的分割线。

代码如下:
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        //任务1
        for (int i = 0; i < 2; i++) {
            NSLog(@"我是任务一、来自线程:%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //任务2
        for (int i = 0; i < 2 ; i++) {
            NSLog(@"我是任务二、来自线程:%@",[NSThread currentThread]);
        }
    });
    
    
    dispatch_barrier_async(queue, ^{
        //栅栏
        for (int i = 0; i < 1 ; i++) {
            NSLog(@"我是分割线、来自线程:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        //任务3
        for (int i = 0; i < 1 ; i++) {
            NSLog(@"我是任务三、来自线程:%@",[NSThread currentThread]);
        }
    });

dispatch_barrier_async 、dispatch_barrier_sync区别
直接看如下代码:

1.dispatch_barrier_async

NSLog(@"开始啦");
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    //任务1
    for (int i = 0; i < 2; i++) {
        NSLog(@"我是任务一、来自线程:%@",[NSThread currentThread]);
    }
});
dispatch_async(queue, ^{
    //任务2
    for (int i = 0; i < 2 ; i++) {
        NSLog(@"我是任务二、来自线程:%@",[NSThread currentThread]);
    }
});

  NSLog(@"动啊动啊");
dispatch_barrier_async(queue, ^{
    //珊栏
    for (int i = 0; i < 1 ; i++) {
        NSLog(@"我是分割线、来自线程:%@",[NSThread currentThread]);
    }
});

dispatch_async(queue, ^{
    //任务3
    for (int i = 0; i < 1 ; i++) {
        NSLog(@"我是任务三、来自线程:%@",[NSThread currentThread]);
    }
});
NSLog(@"结束啦");

代码打印结果:

多线程demo[4912:51826] 开始啦
 多线程demo[4912:51826] 动啊动啊
 多线程demo[4912:51882] 我是任务一、来自线程:<NSThread: 0x60000047f740>{number = 3, name = (null)}
 多线程demo[4912:51884] 我是任务二、来自线程:<NSThread: 0x60000047ed00>{number = 4, name = (null)}
 多线程demo[4912:51826] 结束啦
 多线程demo[4912:51884] 我是任务二、来自线程:<NSThread: 0x60000047ed00>{number = 4, name = (null)}
 多线程demo[4912:51882] 我是任务一、来自线程:<NSThread: 0x60000047f740>{number = 3, name = (null)}
 多线程demo[4912:51882] 我是分割线、来自线程:<NSThread: 0x60000047f740>{number = 3, name = (null)}
 多线程demo[4912:51882] 我是任务三、来自线程:<NSThread: 0x60000047f740>{number = 3, name = (null)}

2.dispatch_barrier_sync

代码如下:

NSLog(@"开始啦");
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    //任务1
    for (int i = 0; i < 2; i++) {
        NSLog(@"我是任务一、来自线程:%@",[NSThread currentThread]);
    }
});
dispatch_async(queue, ^{
    //任务2
    for (int i = 0; i < 2 ; i++) {
        NSLog(@"我是任务二、来自线程:%@",[NSThread currentThread]);
    }
});

NSLog(@"动次打次:%@",[NSThread currentThread]);
dispatch_barrier_sync(queue, ^{
    //珊栏
    for (int i = 0; i < 1 ; i++) {
        NSLog(@"我是分割线、来自线程:%@",[NSThread currentThread]);
    }
});

dispatch_async(queue, ^{
    //任务3
    for (int i = 0; i < 1 ; i++) {
        NSLog(@"我是任务三、来自线程:%@",[NSThread currentThread]);
    }
});
NSLog(@"结束啦");

代码打印结果:

 多线程demo[5014:57352] 开始啦
 多线程demo[5014:57352] 动次打次:<NSThread: 0x600000072f00>{number = 1, name = main}
 多线程demo[5014:57400] 我是任务二、来自线程:<NSThread: 0x60000026dd80>{number = 4, name = (null)}
 多线程demo[5014:57404] 我是任务一、来自线程:<NSThread: 0x600000260b80>{number = 3, name = (null)}
 多线程demo[5014:57400] 我是任务二、来自线程:<NSThread: 0x60000026dd80>{number = 4, name = (null)}
 多线程demo[5014:57404] 我是任务一、来自线程:<NSThread: 0x600000260b80>{number = 3, name = (null)}
 多线程demo[5014:57352] 我是分割线、来自线程:<NSThread: 0x600000072f00>{number = 1, name = main}
 多线程demo[5014:57352] 结束啦
 多线程demo[5014:57404] 我是任务三、来自线程:<NSThread: 0x600000260b80>{number = 3, name = (null)}

代码分析:确实分割了前后执行的任务

总结

异步栅栏

通过上面的例子可以发现异步栅栏函数后面的任务可能比这个栅栏函数先执行完,只能保证的是栅栏之前的任务比栅栏任务提前执行完,不能保证栅栏之后的任务比栅栏晚执行完,也就是说栅栏之后的任务很有可能比栅栏任务早执行完。一定能保证的是栅栏之前的任务在栅栏之后的任务前面执行完。

同步栅栏

保证栅栏之前的任务在栅栏之前执行完,栅栏之后的任务在栅栏之后执行完,很规矩的打印出来,不会乱来。 就跟加在同步并发队列里一样,必须得等到这个同步函数里面的任务执行完之后才能执行后面的任务

上一篇下一篇

猜你喜欢

热点阅读