線程蜈亩、任務(wù)和隊列的概念
類型 | 概念 |
---|---|
線程 | 程序執(zhí)行任務(wù)的最小調(diào)度單位 |
任務(wù) | 在GCD中,任務(wù)就是block中要執(zhí)行的代碼塊 |
隊列 | 存放任務(wù)的一個數(shù)組 |
異步前翎、同步 & 并行稚配、串行的特點
名稱 | 特點 |
---|---|
異步執(zhí)行 | 語句執(zhí)行結(jié)束的順序和語句執(zhí)行開始的順序不一定相同,具備有開啟新線程的能力 |
同步執(zhí)行 | 語句執(zhí)行結(jié)束的順序和語句執(zhí)行開始的順序相同港华,不具備開啟新線程的能力 |
并行隊列 | 隊列中的任務(wù)同時執(zhí)行 |
串行隊列 | 隊列中的任務(wù)按添加順序執(zhí)行(先進先出) |
組合
|并行隊列|串行隊列 |主隊列
----|----|----|----
異步執(zhí)行| 開啟多個線程道川,任務(wù)同時執(zhí)行|開啟一個新線程,任務(wù)按順序執(zhí)行|不開啟新線程任務(wù)按順序執(zhí)行
同步執(zhí)行|不開啟新線程立宜,任務(wù)按順序執(zhí)行|不開啟新線程冒萄,任務(wù)按順序執(zhí)行|會因為任務(wù)互相等待,造成死鎖
代碼詳解
異步執(zhí)行+并行隊列
- (void)testGCD {
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延時代碼的執(zhí)行結(jié)果是:1 3 2
打開延時代碼的執(zhí)行結(jié)果是:1 2 3
由此我們可以得知dispatch_async當中的任務(wù)在另一個線程中異步執(zhí)行橙数,由于我們無法得知在RunLoop中兩個線程的執(zhí)行順序宦言,所以結(jié)果可以是132和123
異步執(zhí)行+串行隊列
- (void)testGCD {
NSLog(@"1");
dispatch_async(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
//[NSThread sleepForTimerInterval:5];
NSLog(@"2");
})
dispatch_async(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
NSLog(@"3");
})
}
屏蔽延時代碼的執(zhí)行結(jié)果是:1 2 3
打開延時代碼的執(zhí)行結(jié)果是:1 2 3
由此我們可知dispatch_async當中的多任務(wù)在同一個線程中根據(jù)添加進隊列的順序同步執(zhí)行
異步執(zhí)行+主隊列
- (void)testGCD {
NSLog(@"1");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延時代碼的執(zhí)行結(jié)果是:1 3 2
打開延時代碼的執(zhí)行結(jié)果是:1 3 2
主隊列的任務(wù)只能在主線程中執(zhí)行,所以加進dispatch_async的任務(wù)會根據(jù)添加進主隊列的順序同步執(zhí)行
同步執(zhí)行+并行隊列
- (void)testGCD {
NSLog(@"1");
dispatch_sync(dispatch_get_global_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延時代碼的執(zhí)行結(jié)果是:1 2 3
打開延時代碼的執(zhí)行結(jié)果是:1 2 3
由于dispatch_sync沒有開啟新線程的能力商模,所以所有任務(wù)按照添加順序在主線程中按順序同步執(zhí)行
同步執(zhí)行+串行隊列
- (void)testGCD {
NSLog(@"1");
dispatch_sync(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
//[NSThread sleepForTimerInterval:5];
NSLog(@"2");
})
dispatch_sync(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
NSLog(@"3");
})
}
屏蔽延時代碼的執(zhí)行結(jié)果是:1 2 3
打開延時代碼的執(zhí)行結(jié)果是:1 2 3
原因同上奠旺,只要是沒有開啟新線程,在主線程中任務(wù)就得按照添加順序執(zhí)行
同步執(zhí)行+主隊列
- (void)testGCD {
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延時代碼的執(zhí)行結(jié)果是:死鎖
打開延時代碼的執(zhí)行結(jié)果是:死鎖
主隊列的任務(wù)要按照添加順序執(zhí)行施流,即132响疚,而同步執(zhí)行是按照代碼添加順序執(zhí)行,即123瞪醋。所以2在等待3執(zhí)行結(jié)束忿晕,3在等待2執(zhí)行結(jié)束,結(jié)果就造成了死鎖