iOS多任務(wù)并發(fā)設(shè)計(jì)

問(wèn)題假如現(xiàn)在有1w個(gè)任務(wù)需要執(zhí)行,并且在全部執(zhí)行完成之后進(jìn)行一個(gè)提示,該怎么做?

思路1:最直接的會(huì)想到dispatch_group,本身就是為一組任務(wù)設(shè)計(jì)的

#define OPERATION_COUNT         10000
#define OPERATION_SLEEP_TIME    0.01f

- (void)myOperation:(NSInteger)index {
    [NSThread sleepForTimeInterval:OPERATION_SLEEP_TIME];    
}

- (void)runMyOperationsWithGCD {
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < OPERATION_COUNT; i++) {
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            [self myOperation:i];
        });
    }
    
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"operations are finished");
    });
}

思考1:這段代碼看的應(yīng)該非常清爽,但是會(huì)創(chuàng)建過(guò)多的線程,也給系統(tǒng)帶來(lái)了巨大的負(fù)擔(dān),是需要優(yōu)化的。


問(wèn)題假設(shè)在原始問(wèn)題的基礎(chǔ)上約束最多10個(gè)并發(fā)線程,又有什么好的辦法?

思路2:采用iOS的NSOperationQueue,這個(gè)東西簡(jiǎn)直是按照這種需求設(shè)計(jì)的,非常好用

#define MAX_CONCURRENT_COUNT 10
#define OPERATION_COUNT     10000
#define OPERATION_SLEEP_TIME    0.1f

- (void)myOperation:(NSInteger)index {
    NSLog(@"enter myOperation:%ld, thread:%@", (long)index, [NSThread currentThread]);
    [NSThread sleepForTimeInterval:OPERATION_SLEEP_TIME];    
}

- (void)runMyOPerationsWithNSOperation {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = MAX_CONCURRENT_COUNT;//設(shè)置最大并發(fā)數(shù)
    for (int i = 0; i < OPERATION_COUNT; i++) {
        [queue addOperationWithBlock:^{
            [self myOperation:i];
        }];
    }
        
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [queue waitUntilAllOperationsAreFinished];//等待所有任務(wù)完成
        NSLog(@"operations are finished");
    });
}

思考2:個(gè)人覺得,這是最方便的方法,簡(jiǎn)單明了,沒有過(guò)多的線程和冗余的代碼。


問(wèn)題如果不使用NSOperation,又有什么好的辦法嗎?

思路3:通過(guò)信號(hào)量控制并發(fā),并結(jié)合思路1的dispatch_group實(shí)現(xiàn)組任務(wù)完成后的通知

#define MAX_CONCURRENT_COUNT 10
#define OPERATION_COUNT     10000
#define OPERATION_SLEEP_TIME    0.1f

- (void)myOperation:(NSInteger)index {
    NSLog(@"enter myOperation:%ld, thread:%@", (long)index, [NSThread currentThread]);
    [NSThread sleepForTimeInterval:OPERATION_SLEEP_TIME];
}

- (void)runMyOperationsWithSemaphore {
    //創(chuàng)建信號(hào)量,控制最大并發(fā)數(shù)為10
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(MAX_CONCURRENT_COUNT);
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < OPERATION_COUNT; i++) {
        //wait一次,semaphore減一,當(dāng)semaphore小于0時(shí)會(huì)一直wait
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            [self myOperation:i];
            //任務(wù)完成后,觸發(fā)semaphore,以允許新的任務(wù)進(jìn)入
            dispatch_semaphore_signal(semaphore);
        });
    }

    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"operations are finished");
    });
}

思考3:這種方式其實(shí)是在思路1的基礎(chǔ)上增加了信號(hào)量的并發(fā)限制,相當(dāng)于一種簡(jiǎn)單的改進(jìn)。

最后,如果采用最傳統(tǒng)的NSThread,跟信號(hào)量配合,可以實(shí)現(xiàn)多任務(wù)并發(fā),但如何判斷所有任務(wù)都已執(zhí)行完畢,只想到了通過(guò)計(jì)數(shù)的方式,并沒有想到更好的辦法。如果大家有更好的辦法,歡迎留言,私信!

最最后,附上demo,地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 背景 擔(dān)心了兩周的我終于輪到去醫(yī)院做胃鏡檢查了!去的時(shí)候我都想好了最壞的可能(胃癌),之前在網(wǎng)上查的癥狀都很相似。...
    Dely閱讀 9,380評(píng)論 21 42
  • Dispatch Queues dispatch queues是執(zhí)行任務(wù)的強(qiáng)大工具,允許你同步或異步地執(zhí)行任意代碼...
    YangPu閱讀 702評(píng)論 0 4
  • 原創(chuàng)內(nèi)容,轉(zhuǎn)載請(qǐng)注明出處: http://www.itdecent.cn/p/ac11fe7ef78c 前言 多線...
    抱緊我的小鯉魚閱讀 8,894評(píng)論 6 78
  • 昨天看完松哥的演講,其實(shí)內(nèi)心是低落的,用生命經(jīng)歷生活的人,是能帶其他人沉重的生命思考!同樣是支教,用心與否,從結(jié)果...
    船長(zhǎng)Captain閱讀 633評(píng)論 1 6
  • 22:00,沒有消息。抱著僥幸的心理,繼續(xù)等。 22:15,還是沒有消息…… 22:30,手機(jī)依然沒有半點(diǎn)聲響。至...
    昵稱空白閱讀 545評(píng)論 12 8

友情鏈接更多精彩內(nèi)容