iOS 多線程的簡單理解(1) 方式 :同步 異步

最近遇到特別糟糕的面試,過程當中提到屢次對多線程的處理問題,並無很好的給予答覆和解決,因此在這裏作個簡單的備案:面試

指望能更加了解和熟練使用 多線程技術:多線程

 

下面都是本身的總結,若是存在不對的,或者不足,請給予指正……異步

 

1. 多線程基本概念:方式 -> 同步 + 異步async

 

1.1 同步 :  隊列任務 在當前線程,按照添加前後順序執行,不開闢新的線程;spa

 

1.1.1   同步方法 1線程

- (void)syncOne{
  
    NSLog(@"**************同步1 start ***************");
    NSLog(@"同步1 start  %@",[NSThread currentThread]);

    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]);
        }
    });
    NSLog(@"同步1 end  %@",[NSThread currentThread]);
    NSLog(@"**************同步1 end ***************");
}

 

 打印結果:::::3d

2017-12-19 16:56:06.537696+0800 DeadThread[6767:1309336] **************同步1 start ***************
2017-12-19 16:56:06.537841+0800 DeadThread[6767:1309336] 同步1 start  <NSThread: 0x6040000789c0>{number = 1, name = main}
2017-12-19 16:56:06.537969+0800 DeadThread[6767:1309336] 同步1   <NSThread: 0x6040000789c0>{number = 1, name = main}
2017-12-19 16:56:06.538046+0800 DeadThread[6767:1309336] 同步1   <NSThread: 0x6040000789c0>{number = 1, name = main}
2017-12-19 16:56:06.538222+0800 DeadThread[6767:1309336] 同步1   <NSThread: 0x6040000789c0>{number = 1, name = main}
2017-12-19 16:56:06.538307+0800 DeadThread[6767:1309336] 同步1 end  <NSThread: 0x6040000789c0>{number = 1, name = main}
2017-12-19 16:56:06.538404+0800 DeadThread[6767:1309336] **************同步1 end ***************

 

獲得的結果::blog

1.建立了同步隊列:dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);隊列

1.線程在主線程執行get

2.線程順序執行的

 

1.1.2 同步方法 2

- (void)syncTwo{
    
    NSLog(@"**************同步2 start ***************");
    NSLog(@"同步2 start  %@",[NSThread currentThread]);

    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    // 同步執行
    dispatch_async(dispatch_get_global_queue(0, 0), ^{//新開一個子線程
        
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"同步2   %@",[NSThread currentThread]);
            }
        });
   
    });
    
    NSLog(@"同步2 end  %@",[NSThread currentThread]);
    NSLog(@"**************同步2 end ***************");
}

 

 打印結果::::

2017-12-20 10:08:49.982236+0800 DeadThread[8035:1857644] **************同步2 start ***************
2017-12-20 10:08:49.982373+0800 DeadThread[8035:1857644] 同步2 start  <NSThread: 0x604000075480>{number = 1, name = main}
2017-12-20 10:08:49.982478+0800 DeadThread[8035:1857644] 同步2 end  <NSThread: 0x604000075480>{number = 1, name = main}
2017-12-20 10:08:49.982512+0800 DeadThread[8035:1858341] 同步2   <NSThread: 0x60400026aa40>{number = 3, name = (null)}
2017-12-20 10:08:49.982563+0800 DeadThread[8035:1857644] **************同步2 end ***************
2017-12-20 10:08:49.982584+0800 DeadThread[8035:1858341] 同步2   <NSThread: 0x60400026aa40>{number = 3, name = (null)}
2017-12-20 10:08:49.982817+0800 DeadThread[8035:1858341] 同步2   <NSThread: 0x60400026aa40>{number = 3, name = (null)}

 

 獲得的結果:::::

 1.線程在新開的線程執行;

 2.線程內同步代碼 運行是順序進行的

 

1.1.3 同步死鎖

  解說一個經典的死鎖代碼:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"開始啓動");// 1
    
    dispatch_sync(dispatch_get_main_queue(), ^{ //2
        
        NSLog(@"同步任務"); // 3 
    });
 
    NSLog(@"啓動結束"); //4
}

 

 運行結果::::

2017-12-20 10:53:10.147278+0800 DeadThread[8403:2037075] 開始啓動
(lldb) 

 

 解說緣由::::

 前提::1. viewDidLoad 任務是在主線程執行的  2. dispatch_sync(dispatch_get_main_queue(),^{ }); 在主線程 添加了新的任務

 1.項目總體代碼是 順序運行的;

 2.當代碼 運行到 標記 1 時, 沒有發生問題,log 正常啓動,打印輸出;

 3.當代碼 運行到 標記 2 時,添加了新的同步任務,且在同一個隊列中(如圖)

 圖示::

 同步任務,view did load 任務 先添加的,因此先被執行,

 運行到  標記 2 時,添加新的同步任務,此時 須要執行 這個同步任務,但此時  view did load 任務 尚未執行完畢;

 形成的結果:

  同步任務 須要等待 view did load 任務執行完畢;

  view did load 任務 須要同步任務執行 完畢;

 

 對不起,哥們,到了這裏,程序死定了,嗚嗚……

 

1.2 異步 :具有開啓新線程的能理,執行時,不影響主線程的運行

 

1.2.1  異步方法1

- (void)asyncOne{
    
    NSLog(@"**************異步1 start ***************");
    NSLog(@"異步1 start  %@",[NSThread currentThread]);
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    // 異步執行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"異步1   %@",[NSThread currentThread]);
        }
    });
    NSLog(@"異步1 end  %@",[NSThread currentThread]);
    NSLog(@"**************異步1 end ***************");
}

 

 執行結果::::

2017-12-20 12:58:01.304660+0800 DeadThread[8552:2189332] **************異步1 start ***************
2017-12-20 12:58:01.304867+0800 DeadThread[8552:2189332] 異步1 start  <NSThread: 0x600000078940>{number = 1, name = main}
2017-12-20 12:58:01.304959+0800 DeadThread[8552:2189332] 異步1 end  <NSThread: 0x600000078940>{number = 1, name = main}
2017-12-20 12:58:01.304993+0800 DeadThread[8552:2189855] 異步1   <NSThread: 0x600000272140>{number = 3, name = (null)}
2017-12-20 12:58:01.305164+0800 DeadThread[8552:2189332] **************異步1 end ***************
2017-12-20 12:58:01.305184+0800 DeadThread[8552:2189855] 異步1   <NSThread: 0x600000272140>{number = 3, name = (null)}
2017-12-20 12:58:01.305255+0800 DeadThread[8552:2189855] 異步1   <NSThread: 0x600000272140>{number = 3, name = (null)}

 

 獲得的結果:::

1.不影響主線程的執行;

2.新任務的代碼,在新的線程執行;

 

1.2.2 異步方法2

- (void)asyncTwo{
    
    NSLog(@"**************異步2 start ***************");
    NSLog(@"異步2 start  %@",[NSThread currentThread]);
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    // 異步執行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"異步2   %@",[NSThread currentThread]);
        }
    });
    NSLog(@"異步2 end  %@",[NSThread currentThread]);
    NSLog(@"**************異步2 end ***************");
}

 

 執行結果:::

2017-12-20 13:16:36.866651+0800 DeadThread[8737:2276498] **************異步2 start ***************
2017-12-20 13:16:36.866783+0800 DeadThread[8737:2276498] 異步2 start  <NSThread: 0x600000076540>{number = 1, name = main}
2017-12-20 13:16:36.866890+0800 DeadThread[8737:2276498] 異步2 end  <NSThread: 0x600000076540>{number = 1, name = main}
2017-12-20 13:16:36.866891+0800 DeadThread[8737:2276887] 異步2   <NSThread: 0x608000079800>{number = 3, name = (null)}
2017-12-20 13:16:36.866960+0800 DeadThread[8737:2276498] **************異步2 end ***************
2017-12-20 13:16:36.866980+0800 DeadThread[8737:2276887] 異步2   <NSThread: 0x608000079800>{number = 3, name = (null)}
2017-12-20 13:16:36.867038+0800 DeadThread[8737:2276887] 異步2   <NSThread: 0x608000079800>{number = 3, name = (null)}

 

 獲得結果:::

1.不影響主線程的執行;

2.新任務的代碼,在新的線程執行;

相關文章
相關標籤/搜索