一个工具,一套API的出现必定会有他的使用场景,多写代码的好处之一就是能碰到更多的这样的场景 然后才会想到使用该工具或者相关的API,GCD更是这样,当你有多线程的需求的时候,就会感觉到它的方便
场景1:APP首页一启动要加载许多页面和数据导致启动缓慢,影响UI操作,此时可以将耗时的非UI操作放到后台线程,用GCD的多线程异步添加到全局并发队列处理
场景2:单例的线程安全,多线程之中单例未必是线程安全的,有一个可能性是在某个线程(就叫它线程A)上进入if语句块并可能在对象分配内存前发生一个上下文切换。然后另一个线程(线程B)可能进入if,分配单例实例的内存,然后退出。这个时候用GCD的单例就是线程安全的
场景3:处理读者与写者问题,OC中的可变对象 通常不是线程安全的,GCD 通过用dispatch barriers创建一个读者写者锁提供了一个优雅的解决方案,dispatch barriers最好创建在自己创建的并发队列中,dispatch barriers通过 一个时刻只执行一个block的机制(和串行队列大概意思一样,保证同一时刻只有一个blcok 执行),来保证线程安全。
关于何时使用dispatch_sync:
自定义串行队列:在这个状况下要非常小心!如果你正运行在一个队列并调用dispatch_sync放在同一个队列,那你就百分百地创建了一个死锁。
主队列(串行):同上面的理由一样,必须非常小心!这个状况同样有潜在的导致死锁的情况。(在主队列中使用dispatch_sync,dispatch_sync中的block也许会添加中主队列中,但当前正在执行的主队列的任务完成不了,所以dispatch_sync的block也不会执行)
并发队列:这才是做同步工作的好选择,不论是通过调度障碍,或者需要等待一个任务完成才能执行进一步处理的情况。
场景4,对多个异步任务的完成进行监控,比如在多个任务下载完成后执行某段代码
Dispatch Groups(调度组)
Dispatch Group 会在整个组的任务都完成时通知你。这些任务可以是同步的,也可以是异步的,即便在不同的队列也行。而且在整个组的任务都完成时,Dispatch Group 可以用同步的或者异步的方式通知你。因为要监控的任务在不同队列,那就用一个dispatch_group_t的实例来记下这些不同的任务。
场景5,控制多个消费者对有限数量资源的访问
信号量:信号量让你控制多个消费者对有限数量资源的访问。举例来说,如果你创建了一个有着两个资源的信号量,那同时最多只能有两个线程可以访问临界区。其他想使用资源的线程必须在一个…你猜到了吗?…FIFO队列里等待
1. 先创建一个Dispatch Semaphore对象,用整数值表示资源的可用数量
2.在每个任务中,调用dispatch_semaphore_wait来等待
3.获得资源就可以进行操作
4.操作完后调用dispatch_semaphore_signal来释放资源
参考文章地址:
https://github.com/nixzhu/dev-blog/blob/master/2014-04-19-grand-central-dispatch-in-depth-part-1.md
https://github.com/nixzhu/dev-blog/blob/master/2014-05-14-grand-central-dispatch-in-depth-part-2.md
(未完待续)