iOS多執行緒(NSThread、NSOperation、GCD)程式設計
全域性併發佇列的獲取方法(需要傳入兩個引數。第一個引數表示佇列優先順序,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT。第二個引數暫時沒用,用0即可)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
4.組合形式:
雖然使用 GCD 只需兩步,但是既然我們有三種佇列(序列佇列/併發佇列/主佇列),兩種任務執行方式(同步執行/非同步執行),那麼我們就有了六種不同的組合方式。這六種不同的組合方式是:
區別 | 併發隊列 | 序列隊列 | 主隊列 |
同步(sync) | 沒 | 沒有開啟新線程,序列執行任務 | 沒有開啟新線程,序列執行任務 |
非同步(async) | 有開啟新線程,併發執行任務 | 有開啟新線程(1條),序列執行任務 | 沒有開啟新線程,序列執行任務 |
//**************** 1、同步執行 + 併發佇列
//在當前執行緒中執行任務,不會開啟新執行緒,執行完一個任務,再執行下一個任務。
/**
* 同步執行 + 併發佇列
* 特點:在當前執行緒中執行任務,不會開啟新執行緒,執行完一個任務,再執行下一個任務。
*/
- (void)syncConcurrent {
NSLog(@"currentThread---%@",[NSThreadcurrentThread]);
NSLog(@"syncConcurrent---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@"
}
});
dispatch_sync(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_sync(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
NSLog(@"syncConcurrent---end");
}
//**************** 2、非同步執行 + 併發佇列
//可以開啟多個執行緒,任務交替(同時)執行。
/**
* 非同步執行 + 併發佇列
* 特點:可以開啟多個執行緒,任務交替(同時)執行。
*/
- (void)asyncConcurrent {
NSLog(@"currentThread---%@",[NSThreadcurrentThread]); // 列印當前執行緒
NSLog(@"asyncConcurrent---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_async(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_async(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
NSLog(@"asyncConcurrent---end");
}
//**************** 3、同步執行 + 序列佇列
//不會開啟新執行緒,在當前執行緒執行任務。任務是序列的,執行完一個任務,再執行下一個任務。
/**
* 同步執行 + 序列佇列
* 特點:不會開啟新執行緒,在當前執行緒執行任務。任務是序列的,執行完一個任務,再執行下一個任務。
*/
- (void)syncSerial {
NSLog(@"currentThread---%@",[NSThreadcurrentThread]); // 列印當前執行緒
NSLog(@"syncSerial---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_sync(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_sync(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
NSLog(@"syncSerial---end");
}
//**************** 4、非同步執行 + 序列佇列
//會開啟新執行緒,但是因為任務是序列的,執行完一個任務,再執行下一個任務
/**
* 非同步執行 + 序列佇列
* 特點:會開啟新執行緒,但是因為任務是序列的,執行完一個任務,再執行下一個任務。
*/
- (void)asyncSerial {
NSLog(@"currentThread---%@",[NSThreadcurrentThread]); // 列印當前執行緒
NSLog(@"asyncSerial---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_async(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_async(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
NSLog(@"asyncSerial---end");
}
//**************** 5、同步執行 + 主佇列
//同步執行 + 主佇列在不同執行緒中呼叫結果也是不一樣,在主執行緒中呼叫會出現死鎖,而在其他執行緒中則不會。
/**
* 同步執行 + 主佇列
* 特點(主執行緒呼叫):互等卡主不執行。
* 特點(其他執行緒呼叫):不會開啟新執行緒,執行完一個任務,再執行下一個任務。
*/
- (void)syncMain {
NSLog(@"currentThread---%@",[NSThreadcurrentThread]); // 列印當前執行緒
NSLog(@"syncMain---begin");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_sync(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_sync(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
NSLog(@"syncMain---end");
}
//**************** 6、非同步執行 + 主佇列
//只在主執行緒中執行任務,執行完一個任務,再執行下一個任務。
/**
* 非同步執行 + 主佇列
* 特點:只在主執行緒中執行任務,執行完一個任務,再執行下一個任務
*/
- (void)asyncMain {
NSLog(@"currentThread---%@",[NSThreadcurrentThread]); // 列印當前執行緒
NSLog(@"asyncMain---begin");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_async(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
dispatch_async(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThreadcurrentThread]); // 列印當前執行緒
}
});
NSLog(@"asyncMain---end");
}