源碼塊一:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@",[NSThread currentThread]);
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"Hello World");
});
}
分析:
- 當前dispatch_sync()函數(shù)在主線程中調(diào)用,可以用 NSLog(@"%@",[NSThread currentThread]); 驗證
- 調(diào)用dispatch_sync()函數(shù)會立即阻塞調(diào)用時該函數(shù)所在的線程,即主線程等待dispatch_sync()函數(shù)返回
- dispatch_sync()函數(shù)追加任務(即Block代碼塊)到主隊列dispatch_get_main_queue()中,主隊列是一種特殊的串行隊列
- 主隊列的任務在主線程中執(zhí)行,但此時主線程被阻塞,無法執(zhí)行Block代碼塊,導致dispatch_sync()函數(shù)無法返回,一直等待Block被主線程執(zhí)行
- 最終導致死鎖
源碼塊二:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"1-----%@",[NSThread currentThread]);
//創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
//異步函數(shù)產(chǎn)生一個新的線程
dispatch_async(queue, ^{
NSLog(@"2-----%@",[NSThread currentThread]);
//向新線程中用同步函數(shù)dispatch_sync()追加任務
dispatch_sync(queue, ^{
NSLog(@"3-----%@",[NSThread currentThread]);
});
});
}
控制臺:
1-----<NSThread: 0x7ff8aad00220>{number = 1, name = main}
2-----<NSThread: 0x7ff8aad11670>{number = 2, name = (null)}
分析:
- 在產(chǎn)生的新的線程(number = 2 , name = (null))中,調(diào)用函數(shù)dispatch_sync(),立即阻塞當前線程,即新開的線程,此時線程阻塞,等待dispatch_sync()函數(shù)返回.
- 使用 dispatch_sync() 追加任務NSLog(@"3-----%@",[NSThread currentThread]);到隊列queue中, 但是當前線程被阻塞,無法執(zhí)行Block代碼塊,Block代碼塊等待被線程執(zhí)行.
- 最終導致死鎖.
源碼塊三:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"1-----%@",[NSThread currentThread]);
//創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
//異步函數(shù)產(chǎn)生一個新的線程
dispatch_async(queue, ^{
NSLog(@"2-----%@",[NSThread currentThread]);
//創(chuàng)建一個新的串行隊列
dispatch_queue_t queue2 = dispatch_queue_create("newQueue", DISPATCH_QUEUE_SERIAL);
//在新線程中用同步函數(shù)dispatch_sync()向新建的串行隊列中追加任務
dispatch_sync(queue2, ^{
NSLog(@"3-----%@",[NSThread currentThread]);
});
});
}
控制臺:
1-----<NSThread: 0x7fe5daf01730>{number = 1, name = main}
2-----<NSThread: 0x7fe5dac448f0>{number = 2, name = (null)}
3-----<NSThread: 0x7fe5dac448f0>{number = 2, name = (null)}
可以看到該代碼塊并沒有產(chǎn)生死鎖,但是queue2隊列也是在新線程中,為什么調(diào)用dispatch_sync()函數(shù)時,并沒有阻塞<NSThread: 0x7fe5dac448f0>{number = 2, name = (null)}這條線程,從而使得dispatch_sync()中的任務在新線程中被執(zhí)行.
那么我的問題就是: 用異步函數(shù)創(chuàng)建新線程時所用到的隊列,即代碼中的queue
dispatch_async(queue, ^{
NSLog(@"2-----%@",[NSThread currentThread]);
如果為串行隊列(并發(fā)隊列并不會有該情況),那么該隊列 是否可以認為是 該新線程中的 "主隊列",類似于源碼塊一的效果.