-
dispatch_group
和dispatch_barrier
的區(qū)別捻勉?
案例1:如果有A刀森、B、C 三個任務(wù)埠偿,需要三個任務(wù)(可能耗時)執(zhí)行結(jié)束后再執(zhí)行任務(wù)D榜晦,怎么實現(xiàn)?
- 第一種方案使用
dispatch_group
注意:dispatch_group_enter
和dispatch_group_leave
是成對出現(xiàn)
NSLog(@"dispatch_group");
dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)A");
[NSThread sleepForTimeInterval:3];
NSLog(@"結(jié)束任務(wù)A");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)B");
[NSThread sleepForTimeInterval:2];
NSLog(@"結(jié)束任務(wù)B");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)C");
[NSThread sleepForTimeInterval:1];
NSLog(@"結(jié)束任務(wù)C");
dispatch_group_leave(group);
});
// 當(dāng)所有任務(wù)執(zhí)行結(jié)束后才執(zhí)行以下代碼
dispatch_group_notify(group, queue, ^{
NSLog(@"----------> group <----------");
NSLog(@"開始任務(wù)D");
});
我們看下打印結(jié)果:
dispatch_group.png
- 第二種方案:使用
dispatch_barrier_async
NSLog(@"dispatch_barrier");
dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)A,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:3];
NSLog(@"結(jié)束任務(wù)A");
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)B");
[NSThread sleepForTimeInterval:2];
NSLog(@"結(jié)束任務(wù)B");
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)C");
[NSThread sleepForTimeInterval:1];
NSLog(@"結(jié)束任務(wù)C");
});
// 柵欄函數(shù)
dispatch_barrier_async(queue, ^{
NSLog(@"----------> barrier <----------");
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)D");
});
我們再看下打印結(jié)果:
dispatch_barrier.png
我們發(fā)現(xiàn) dispatch_barrier_async
阻塞了下面的代碼,必須等到上面代碼(耗時)執(zhí)行結(jié)束之后才執(zhí)行下面的代碼愁憔。然而,如果我們把柵欄函數(shù)注釋了再看下打印結(jié)果:
刪除柵欄函數(shù)結(jié)果
但是半抱,我們還是發(fā)現(xiàn) dispatch_group
和 dispatch_barrier_async
都能實現(xiàn)以上需求膜宋,這尼瑪沒區(qū)別啊秋茫,不著急,慢慢看下面這個需求肛著。
案例2:如果有A跺讯、B殉农、C 三個任務(wù),需要三個任務(wù)分別按照順序執(zhí)行結(jié)束后再執(zhí)行任務(wù)D愈污,怎么實現(xiàn)呢聪建?
dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_barrier_async(queue, ^{
NSLog(@"開始任務(wù)A");
[NSThread sleepForTimeInterval:1];
NSLog(@"結(jié)束任務(wù)A");
});
dispatch_barrier_async(queue, ^{
NSLog(@"開始任務(wù)B");
[NSThread sleepForTimeInterval:2];
NSLog(@"結(jié)束任務(wù)B");
});
dispatch_barrier_async(queue, ^{
NSLog(@"開始任務(wù)C");
[NSThread sleepForTimeInterval:3];
NSLog(@"結(jié)束任務(wù)C");
});
dispatch_barrier_async(queue, ^{
NSLog(@"----------> A B C 有順序 <----------");
NSLog(@"開始任務(wù)D");
});
我們看下打印結(jié)果:
有順序執(zhí)行A、B擎析、C任務(wù)
- 我們再聊聊柵欄函數(shù)
dispatch_barrier_async
挥下,看看下面這段代碼:
NSLog(@"dispatch_barrier");
NSLog(@"---------- 1111111111 ----------");
dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)A,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:3];
NSLog(@"結(jié)束任務(wù)A现斋,來自線程:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)B偎蘸,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
NSLog(@"結(jié)束任務(wù)B,來自線程:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)C限书,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:1];
NSLog(@"結(jié)束任務(wù)C章咧,來自線程:%@",[NSThread currentThread]);
});
NSLog(@"---------- 2222222222 ----------");
// 柵欄函數(shù)
dispatch_barrier_async(queue, ^{
NSLog(@"----------> barrier <----------");
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)D,來自線程:%@",[NSThread currentThread]);
});
NSLog(@"---------- 3333333333 ----------");
先看下輸出結(jié)果:
柵欄函數(shù)(異步)
我們第一個問題得出結(jié)論是:柵欄函數(shù)dispatch_barrier_async
確實可以阻塞后面的代碼扰柠,但是這里發(fā)現(xiàn) 這個 33333333 還是先被打印了出來疼约,才執(zhí)行的柵欄函數(shù)。也就是說:柵欄函數(shù)阻塞的是子線程的代碼裆装,主線程的代碼并沒有阻塞。當(dāng)然茎活,這也體現(xiàn)出了 async 異步的特點(diǎn)琢唾。那我們在看看 sync 有什么不一樣的。
NSLog(@"dispatch_barrier_sync");
NSLog(@"---------- 1111111111 ----------");
dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)A采桃,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:3];
NSLog(@"結(jié)束任務(wù)A普办,來自線程:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)B,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
NSLog(@"結(jié)束任務(wù)B衔蹲,來自線程:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)C,來自線程:%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:1];
NSLog(@"結(jié)束任務(wù)C橱健,來自線程:%@",[NSThread currentThread]);
});
NSLog(@"---------- 2222222222 ----------");
// 柵欄函數(shù)(同步)
dispatch_barrier_sync(queue, ^{
NSLog(@"----------> barrier <----------");
});
dispatch_async(queue, ^{
NSLog(@"開始任務(wù)D沙廉,來自線程:%@",[NSThread currentThread]);
});
NSLog(@"---------- 3333333333 ----------");
打印出的結(jié)果:確實分割了前后執(zhí)行的任務(wù)
柵欄函數(shù)(同步)