美文网首页iOS Developer
浅谈:如何实现多条线程执行完后再进行其他操作

浅谈:如何实现多条线程执行完后再进行其他操作

作者: anjohnlv | 来源:发表于2017-07-07 14:00 被阅读32次

假设这么一个使用场景,问要大象放进冰箱里。分为几步?

1、分两拨人分别去找冰箱和大象;
2、找到冰箱后,打开冰箱门,等待大象;
3、找到大象后等待冰箱门打开;
4、都做完之后把大象装进去,关门。

纯洁的我一直这么做:

1、声明一个成员变量finishAmount,初始化为0
2、找到冰箱之后尝试去装一次大象,如果发现finishAmount==0,说明还没找到大象,于是finishAmount++,之后就return了。
3、找到冰箱并开门之后尝试去装一次大象,如果发现finishAmount==0,同上。
4、如果发现如果发现finishAmount==1,说明另一步已经完成了。就可以开心得装大象了。

@implementation OldJob {
    int finishAmount;
}

-(void)putElephantInRefrigerator:(void (^)(NSString *))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self searchRefrigerator];
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self searchElephant];
    });
}

-(void)searchRefrigerator {
    sleep(5);
    NSLog(@"找到冰箱了");
    [self openRefrigeratorDoor];
}

-(void)openRefrigeratorDoor {
    NSLog(@"开门了");
    [self everythingIsOk];
}

-(void)searchElephant {
    sleep(3);
    NSLog(@"找到大象了");
    [self everythingIsOk];
}

-(void)everythingIsOk {
    if(finishAmount == 0) {
        finishAmount++;
        return;
    }
    NSLog(@"everythingIsOk");
}

直到有一天突然想装逼了,我要知道你找冰箱的每一步状态:

@implementation MyJob {
    dispatch_semaphore_t semaphore;
    dispatch_group_t group;
    dispatch_queue_t queue;
}

-(instancetype)init {
    self = [super init];
    if (self) {
        semaphore = dispatch_semaphore_create(0);
        group = dispatch_group_create();
        queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    }
    return self;
}

-(void)putElephantInRefrigerator:(void (^)(NSString *))completion {
    dispatch_group_notify(group, queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        [self everythingIsOk:completion];
    });
    dispatch_group_async(group, queue, ^{
        [self searchRefrigerator:completion];
    });
    dispatch_group_async(group, queue, ^{
        [self searchElephant];
    });
}

-(void)searchRefrigerator:(void (^)(NSString *))completion {
    sleep(5);
    if (completion) {
        completion(@"找到冰箱啦");
    }
    [self openRefrigeratorDoor:completion];
}

-(void)openRefrigeratorDoor:(void (^)(NSString *))completion {
    if (completion) {
        completion(@"门打开啦");
    }
    dispatch_semaphore_signal(semaphore);
}

-(void)searchElephant {
    sleep(3);
    dispatch_semaphore_signal(semaphore);
}

-(void)everythingIsOk:(void (^)(NSString *))completion {
    if (completion) {
        completion(@"everythingIsOk");
    }
}

利用dispatch_group_notify的特性,在相同group全部返回了,才会执行。在这里,如果先执行

    dispatch_group_async(group, queue, ^{
        [self searchRefrigerator:completion];
    });
    dispatch_group_async(group, queue, ^{
        [self searchElephant];
    });

再执行

    dispatch_group_notify(group, queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        [self everythingIsOk:completion];
    });

则可以直接达到预期效果,但是我们在实际的应用场合中,复杂的网络请求往往并不能按照理想的按部就班。于是我们在这加上了dispatch_semaphore_wait
如在本例中,dispatch_group_notify先于dispatch_group_async调用。调用时发现已没有未执行的dispatch_group_async,便会直接执行,而不能达到确保其他接口都执行完了再执行的需求。
加上dispatch_semaphore_wait后,执行时会等待dispatch_semaphore_signal激活,需要多个接口返回便加上多个等待即可。

相关文章

  • 浅谈:如何实现多条线程执行完后再进行其他操作

    假设这么一个使用场景,问要大象放进冰箱里。分为几步? 1、分两拨人分别去找冰箱和大象;2、找到冰箱后,打开冰箱门,...

  • CountDownLatch

    CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。什么...

  • CountDownLatch简单使用

    简述 CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行...

  • java 多线程CountDownLatch

    CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行 Co...

  • 【并发】CountDownLatch

    作用 它允许一个或多个线程一直等待其他线程的执行完后再执行。 如何使用(demo) 1、先创建线程池 2、建立任务...

  • 什么时候使用CountDownLatch

    CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。在J...

  • JAVA多线程-CountDownLatch计数器

    一、概述 CountDownLatch是一个同步工具类,它允许一个或多个线程等待其他线程执行完操作之后再继续执行。...

  • iOS 多线程:NSOperation、NSOperationQ

    线程安全解决方案:可以给线程加锁,在一个线程执行该操作的时候,不允许其他线程进行操作。iOS 实现线程加锁有很多种...

  • Java基础(五)-多线程-2

    问:如何实现子线程先执行,主线程再执行答: 启动子线程后,立即调用该线程的join()方法,则主线程必须等待子线程...

  • java并发包之CountDownLatch

    一、前言 CountDownLatch是一个同步辅助器,用于一个线程等待多个线程执行完操作后再执行。 二、主要特点...

网友评论

    本文标题:浅谈:如何实现多条线程执行完后再进行其他操作

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