iOS 多線程的簡單理解(2) 隊列 :串行 ,並行,MainQueue,GlobalQueue


 

多線程隊列是裝載線程任務的隊形結構。(系統以先進先出的方式調度隊列中的任務執行 FIFO)。在GCD中有兩種隊列:

串行隊列、並發隊列。

 

隊列 :串行隊列、並發隊列,全局主對列,全局並發隊列

 

2.1.  串行隊列:線程只能依次有序的執行。

 

2.1.1 串行方法 1

- (void)SerialQueueOne{
     
    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   index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 10; i < 13; i++) {
            NSLog(@"串行1   index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"串行1 end :::%@",[NSThread currentThread]);
}

 

 執行結果:::

2017-12-20 13:49:47.427330+0800 DeadThread[8972:2450330] 串行1 start :::<NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427470+0800 DeadThread[8972:2450330] 串行1   index 0 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427567+0800 DeadThread[8972:2450330] 串行1   index 1 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427636+0800 DeadThread[8972:2450330] 串行1   index 2 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427696+0800 DeadThread[8972:2450330] 串行1   index 10 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427819+0800 DeadThread[8972:2450330] 串行1   index 11 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427893+0800 DeadThread[8972:2450330] 串行1   index 12 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
2017-12-20 13:49:47.427966+0800 DeadThread[8972:2450330] 串行1 end :::<NSThread: 0x60800006ae80>{number = 1, name = main}

 

 得到結果:::

 1.代碼順序 執行;

 

2.1.2 串行方法 2

- (void)SerialQueueTwo{
    
    NSLog(@"串行2 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(@"串行2   index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 10; i < 13; i++) {
            NSLog(@"串行2   index %d ::: %@",i,[NSThread currentThread]);
        }
    });

       NSLog(@"串行2 end :::%@",[NSThread currentThread]); 
}

 

 執行結果:::

2017-12-20 13:50:47.130380+0800 DeadThread[8993:2458517] 串行1 start :::<NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.130533+0800 DeadThread[8993:2458517] 串行1   index 0 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.130648+0800 DeadThread[8993:2458517] 串行1   index 1 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.130724+0800 DeadThread[8993:2458517] 串行1   index 2 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.130896+0800 DeadThread[8993:2458517] 串行1   index 10 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.130979+0800 DeadThread[8993:2458517] 串行1   index 11 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.131057+0800 DeadThread[8993:2458517] 串行1   index 12 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
2017-12-20 13:50:47.131130+0800 DeadThread[8993:2458517] 串行1 end :::<NSThread: 0x60c000071300>{number = 1, name = main}

 

 得到結果:::

1.沒有開啟線程

2.代碼順序執行;

 

2.2 並發隊列:線程可以同時一起進行執行。實際上是CPU在多條線程之間快速的切換。(並發功能只有在異步(dispatch_async)函數下才有效)

 

2.2.1 並發方法 1

- (void)concurrentQueueOne{
    
    NSLog(@"並發1 start :::%@",[NSThread currentThread]);

    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"並發1  index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        for (int i = 10; i < 13; i++) {
            NSLog(@"並發1  index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    NSLog(@"並發1 end :::%@",[NSThread currentThread]);
}

 

 執行結果:::

2017-12-20 13:52:37.606997+0800 DeadThread[9023:2470506] 並發1 start :::<NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.607130+0800 DeadThread[9023:2470506] 並發1  index 0 ::: <NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.607197+0800 DeadThread[9023:2470506] 並發1  index 1 ::: <NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.607447+0800 DeadThread[9023:2470506] 並發1  index 2 ::: <NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.607685+0800 DeadThread[9023:2470506] 並發1  index 10 ::: <NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.607891+0800 DeadThread[9023:2470506] 並發1  index 11 ::: <NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.608056+0800 DeadThread[9023:2470506] 並發1  index 12 ::: <NSThread: 0x608000261600>{number = 1, name = main}
2017-12-20 13:52:37.608190+0800 DeadThread[9023:2470506] 並發1 end :::<NSThread: 0x608000261600>{number = 1, name = main}

 

 得到結果:::

1.線程順序執行

 

2.2.2 並發方法 2

- (void)concurrentQueueTwo{
    
    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  index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 10; i < 13; i++) {
            NSLog(@"並發2  index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    NSLog(@"並發2 end :::%@",[NSThread currentThread]);
}

 執行結果::;

2017-12-20 13:56:45.573695+0800 DeadThread[9084:2492640] 並發2 start :::<NSThread: 0x604000077d80>{number = 1, name = main}
2017-12-20 13:56:45.573891+0800 DeadThread[9084:2492640] 並發2 end :::<NSThread: 0x604000077d80>{number = 1, name = main}
2017-12-20 13:56:45.573907+0800 DeadThread[9084:2492674] 並發2  index 0 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
2017-12-20 13:56:45.573908+0800 DeadThread[9084:2492675] 並發2  index 10 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
2017-12-20 13:56:45.574283+0800 DeadThread[9084:2492674] 並發2  index 1 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
2017-12-20 13:56:45.574344+0800 DeadThread[9084:2492675] 並發2  index 11 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
2017-12-20 13:56:45.574420+0800 DeadThread[9084:2492675] 並發2  index 12 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
2017-12-20 13:56:45.574422+0800 DeadThread[9084:2492674] 並發2  index 2 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}

 得到結果:::

1.添加兩個 任務代碼塊,開啟兩個線程;

2.子線程中代碼 不是按順序執行

 

2.3 全局主隊列::::

 

2.3.1  主隊列 同步 死鎖

- (void)syncMain {
 
    NSLog(@"\n\n**************主隊列同步,放到主線程會死鎖***************\n\n");
 
    // 主隊列
    dispatch_queue_t queue = dispatch_get_main_queue();
 
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主隊列同步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主隊列同步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主隊列同步3   %@",[NSThread currentThread]);
        }
    });
}

 死鎖原因:::

    如果在主線程中運用主隊列同步,也就是把任務放到了主線程的隊列中。

    而同步對於任務是立刻執行的,那么當把第一個任務放進主隊列時,它就會立馬執行。

    可是主線程現在正在處理syncMain方法,任務需要等syncMain執行完才能執行。

    syncMain執行到第一個任務的時候,又要等第一個任務執行完才能往下執行第二個和第三個任務。

    這樣syncMain方法和第一個任務就開始了互相等待,形成了死鎖。

 

2.3.2  主隊列 異步

- (void)asyncMain {
 
    NSLog(@"**************主隊列異步***************");
 
    // 主隊列
    dispatch_queue_t queue = dispatch_get_main_queue();
 
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主隊列異步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主隊列異步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主隊列異步3   %@",[NSThread currentThread]);
        }
    });
}

 執行結果:::

2017-12-20 14:20:01.729412+0800 DeadThread[9257:2636939] **************主隊列異步***************
2017-12-20 14:20:01.732208+0800 DeadThread[9257:2636939] 主隊列異步1   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.732326+0800 DeadThread[9257:2636939] 主隊列異步1   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.732456+0800 DeadThread[9257:2636939] 主隊列異步1   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.732726+0800 DeadThread[9257:2636939] 主隊列異步2   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.732931+0800 DeadThread[9257:2636939] 主隊列異步2   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.733026+0800 DeadThread[9257:2636939] 主隊列異步2   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.733128+0800 DeadThread[9257:2636939] 主隊列異步3   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.733251+0800 DeadThread[9257:2636939] 主隊列異步3   <NSThread: 0x604000261080>{number = 1, name = main}
2017-12-20 14:20:01.733502+0800 DeadThread[9257:2636939] 主隊列異步3   <NSThread: 0x604000261080>{number = 1, name = main}

得到結果:::

1. 主隊列是個同步隊列

 

2.4 全局並發隊列

2.4.1

- (void)globalQueueOne{
    
    NSLog(@"global1 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(@"global1  index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        for (int i = 10; i < 13; i++) {
            NSLog(@"global1  index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    NSLog(@"global1 end :::%@",[NSThread currentThread]);
}

 執行結果:::

2017-12-20 14:27:02.302953+0800 DeadThread[9352:2669397] global1 start :::<NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303132+0800 DeadThread[9352:2669397] global1  index 0 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303230+0800 DeadThread[9352:2669397] global1  index 1 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303322+0800 DeadThread[9352:2669397] global1  index 2 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303397+0800 DeadThread[9352:2669397] global1  index 10 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303467+0800 DeadThread[9352:2669397] global1  index 11 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303557+0800 DeadThread[9352:2669397] global1  index 12 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
2017-12-20 14:27:02.303638+0800 DeadThread[9352:2669397] global1 end :::<NSThread: 0x6000000655c0>{number = 1, name = main}

 

2.4.2

- (void)globalQueueTwo{
    
    NSLog(@"global2 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(@"global2   index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 10; i < 13; i++) {
            NSLog(@"global2   index %d ::: %@",i,[NSThread currentThread]);
        }
    });
    
    NSLog(@"global2 end :::%@",[NSThread currentThread]);
}

 執行結果:::

2017-12-20 14:28:27.498062+0800 DeadThread[9382:2678820] global2 start :::<NSThread: 0x600000076700>{number = 1, name = main}
2017-12-20 14:28:27.498208+0800 DeadThread[9382:2678820] global2 end :::<NSThread: 0x600000076700>{number = 1, name = main}
2017-12-20 14:28:27.498250+0800 DeadThread[9382:2679707] global2   index 0 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
2017-12-20 14:28:27.498260+0800 DeadThread[9382:2679706] global2   index 10 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
2017-12-20 14:28:27.498555+0800 DeadThread[9382:2679707] global2   index 1 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
2017-12-20 14:28:27.498692+0800 DeadThread[9382:2679706] global2   index 11 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
2017-12-20 14:28:27.498710+0800 DeadThread[9382:2679707] global2   index 2 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
2017-12-20 14:28:27.498753+0800 DeadThread[9382:2679706] global2   index 12 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM