同步(sync)
和 异步(async)
的主要区别在于会不会阻塞当前线程,直到 Block
中的任务执行完毕!
如果是 同步(sync)
操作,它会阻塞当前线程并等待 Block
中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)
操作,当前线程会直接往下执行,它不会阻塞当前线程。
同步任务会阻塞当前线程,然后把 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())
我们按执行顺序一步步来哦:
- 使用
DISPATCH_QUEUE_SERIAL
这个参数,创建了一个 串行队列。- 打印出
之前 - %@
这句。dispatch_async
异步执行,所以当前线程不会被阻塞,于是有了两条线程,一条当前线程继续往下打印出之后 - %@
这句, 另一台执行 Block 中的内容打印sync之前 - %@
这句。因为这两条是并行的,所以打印的先后顺序无所谓。- 注意,高潮来了。现在的情况和上一个例子一样了。
dispatch_sync
同步执行,于是它所在的线程会被阻塞,一直等到sync
里的任务执行完才会继续往下。于是sync
就高兴的把自己 Block 中的任务放到queue
中,可谁想queue
是一个串行队列,一次执行一个任务,所以sync
的 Block 必须等到前一个任务执行完毕,可万万没想到的是queue
正在执行的任务就是被sync
阻塞了的那个。于是又发生了死锁。所以sync
所在的线程被卡死了。剩下的两句代码自然不会打印。
原文链接:http://www.jianshu.com/p/0b0d9b1f1f19
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
关于GCD 延时操作的事情,一个是开一个异步线程并立即执行block阻塞主线程2s,但是第一个会阻塞主线程,这样做是很为危险的。一个是另开一个线程2s后延时操作
dispatch_async(dispatch_get_main_queue(), {[weak self] in
sleep(2)
//在这里写要做的事情
})
let time = dispatch_time(DISPATCH_TIME_NOW,Int64(2 * NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(),{
//在这里写要做的事情
})
dispatch_async(dispatch_get_global_queue(0, 0)) {() -> Void in
sleep(2)
dispatch_async(dispatch_get_main_queue(), {[weak self] () -> Void in
})
}