- 以下代码在主线程调用,结果是什么?
NSLog("之前 - %@", NSThread.currentThread())
dispatch_sync(dispatch_get_main_queue(), { () -> Void in
NSLog("sync - %@", NSThread.currentThread())
})
NSLog("之后 - %@", NSThread.currentThread())
答案:
只会打印第一句:之前- <NSThread: 0x7fb3a9e16470>{number = 1, name = main}
,然后主线程就卡死了,你可以在界面上放一个按钮,你就会发现点不了了。
解释:
同步任务会阻塞当前线程,然后把 Block
中的任务放到指定的队列中执行,只有等到 Block
中的任务完成后才会让当前线程继续往下运行。
那么这里的步骤就是:打印完第一句后,dispatch_sync
立即阻塞当前的主线程,然后把 Block
中的任务放到 main_queue
中,可是 main_queue
中的任务会被取出来放到主线程中执行,但主线程这个时候已经被阻塞了,所以 Block
中的任务就不能完成,它不完成,dispatch_sync
就会一直阻塞主线程,这就是死锁现象。导致主线程一直卡死。
- 以下代码会产生什么结果?
let queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL)
NSLog("之前 - %@", NSThread.currentThread())
dispatch_async(queue, { () -> Void in
NSLog("sync之前 - %@", NSThread.currentThread())
dispatch_sync(queue, { () -> Void in
NSLog("sync - %@", NSThread.currentThread())
})
NSLog("sync之后 - %@", NSThread.currentThread())
})
NSLog("之后 - %@", NSThread.currentThread())
答案:
2017-04-11 10:06:51.058 test[33329:8793087] 之前 - <NSThread: 0x7fe32050dbb0>{number = 1, name = main}
2017-04-11 10:06:51.059 test[33329:8793356] sync之前 - <NSThread: 0x7fe32062e9f0>{number = 2, name = (null)}
2017-04-11 10:06:51.059 test[33329:8793087] 之后 - <NSThread: 0x7fe32050dbb0>{number = 1, name = main}
很明显 sync - %@
和 sync之后 - %@
没有被打印出来!这是为什么呢?我们再来分析一下:
分析:
使用
DISPATCH_QUEUE_SERIAL
这个参数,创建了一个 串行队列。打印出 之前
- %@
这句。dispatch_async
异步执行,所以当前线程不会被阻塞,于是有了两条线程,一条当前线程继续往下打印出之后 - %@
这句, 另一台执行Block
中的内容打印sync之前 - %@
这句。因为这两条是并行的,所以打印的先后顺序无所谓。注意,重点来了。现在的情况和上一个例子一样了。
dispatch_sync
同步执行,于是它所在的线程会被阻塞,一直等到sync
里的任务执行完才会继续往下。于是sync
就高兴的把自己Block
中的任务放到queue
中,可谁想queue
是一个串行队列,一次执行一个任务,所以sync
的Block
必须等到前一个任务执行完毕,可万万没想到的是queue
正在执行的任务就是被sync
阻塞了的那个。于是又发生了死锁。所以sync
所在的线程被卡死了。剩下的两句代码自然不会打印。