一、多線程的基本概念理解
(1)進程:可以理解成一個運行中的應用程序,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎,主要管理資源。
(2)線程:是進程的基本執行單元,一個進程對應多個線程。
(3)主線程:處理UI,所有更新UI的操作都必須在主線程上執行。不要把耗時操作放在主線程,會卡界面。
(4)多線程:在同一時刻,一個CPU只能處理1條線程,但CPU可以在多條線程之間快速的切換,只要切換的足夠快,就造成了多線程一同執行的假象。
(5)線程就像火車的一節車廂,進程則是火車。車廂(線程)離開火車(進程)是無法跑動的,而火車(進程)至少有一節車廂(主線程)。多線程可以看做多個車廂,它的出現是為了提高效率。
(6)多線程是通過提高資源使用率來提高系統總體的效率。
(7)我們運用多線程的目的是:將耗時的操作放在后臺執行!
二、多線程的四種解決方案分別是:pthread,NSThread,GCD, NSOperation。
三、這里主要介紹一下GCD 的使用
(1):GCD的特點
GCD會自動利用更多的CPU內核
GCD自動管理線程的生命周期(創建線程,調度任務,銷毀線程等)
程序員只需要告訴 GCD 想要如何執行什么任務,不需要編寫任何線程管理代碼
(2)GCD的基本概念
任務(block):任務就是將要在線程中執行的代碼,將這段代碼用block封裝好,然后將這個任務添加到指定的執行方式(同步執行和異步執行),等待CPU從隊列中取出任務放到對應的線程中執行。
同步(sync):一個接著一個,前一個沒有執行完,后面不能執行,不開線程。
異步(async):開啟多個新線程,任務同一時間可以一起執行。異步是多線程的代名詞
隊列:裝載線程任務的隊形結構。(系統以先進先出的方式調度隊列中的任務執行)。在GCD中有兩種隊列:串行隊列和并發隊列。
并發隊列:線程可以同時一起進行執行。實際上是CPU在多條線程之間快速的切換。(并發功能只有在異步(dispatch_async)函數下才有效)
串行隊列:線程只能依次有序的執行。
GCD總結:將任務(要在線程中執行的操作block)添加到隊列(自己創建或使用全局并發隊列),并且指定執行任務的方式(異步dispatch_async,同步dispatch_sync)
//串行隊列
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
//并行隊列
dispatch_queue_t queue1 = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
//主隊列:
dispatch_get_global_queue(0, 0)
//主線程
dispatch_get_main_queue()
//同步執行任務
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
// 任務放在這個block里
NSLog(@"我是同步執行的任務");
});
//異步執行任務
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 任務放在這個block里
NSLog(@"我是異步執行的任務");
});
//隊列創建
//串行隊列創建
dispatch_queue_t queue =dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
// 同步執行
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行同步1 %@",[NSThread currentThread]);
}
});
//柵欄
dispatch_barrier_async(queue, ^{
NSLog(@"------------barrier------------%@", [NSThread currentThread]);
NSLog(@"******* 并發異步執行,在異步執行中加入一道分水嶺,前面是先完成的,后面的 后完成 *********");
});
//線程組
- (void)testGroup {
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"隊列組:有一個耗時操作完成!");
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"隊列組:有一個耗時操作完成!");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"隊列組:前面的耗時操作都完成了,回到主線程進行相關操作");
});
}
通常情況下的 多線程 常規操作是 異步加載主隊列任務,在主隊列里面加載耗時操作,等結束后回到主線程刷新界面
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 耗時操作放在這里
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程進行UI操作
});
});