[TOC]
最近阅读了一些关于gcd的文章有些许感悟
在开发中我们难免会对单个对象进行 高并发处理(尤其是单例),如何优雅的处理保证现场不崩溃
并行和并发
并行 两个或多个任务 在同一时刻进行
并发 两个或多个任务 在相近时间 间隔进行
为了保证高并发对资源的合理分配需要用到线程队列处理
创建一个 队列
///创建线程
let queue = DispatchQueue.init(label: "workQueue", qos: DispatchQoS.default, attributes:
DispatchQueue.Attributes.concurrent, autoreleaseFrequency:
DispatchQueue.AutoreleaseFrequency.workItem, target: nil)
///创建队列
let group = DispatchGroup()
下面是对几个属性的注释
DispatchQoS 表示线程优先级
- .userInteractive 需要用户交互的,优先级最高,和主线程一样
- .userInitiated 即将需要,用户期望优先级,优先级高比较高
- .default 默认优先级
- .utility 需要执行一段时间后,再通知用户,优先级低
- *.background 后台执行的,优先级比较低
- *.unspecified 不指定优先级,最低
autoreleaseFrequency 表示自动释放频率,设置自动释放机制。
- .inherit 表示不确定,之前默认的行为也是现在的默认值
- .workItem 表示为每个执行的项目创建和排除自动释放池, 项目完成时清理临时对象
- .never 表示GCD不为您管理自动释放池
DispatchWorkItemFlags
barrier 栅栏函数: 使并发任务顺序执行
假设我们有一个并发的队列用来读写一个数据对象。
如果这个队列里的操作是读的,那么可以多个同时进行。 如果有写的操作,则必须保证在执行写入操作时,不会有读取操作在执行,必须等待写入
完成后才能读取,否则就可能会出现读到的数据不对。 在之前我们用dipatch_barrier实现。
下面的代码for循环遍历100个异步任务
for i in 0..<100 {
queue.async(group: group, qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
print("线程\(Thread.current)正在执行任务\(i)")
}
}
group.notify(queue:queue) {
print("所有任务全部执行完毕")
}
下面是创建 DispatchWorkItem(任务对象)
print("before waiting")
let workitem = DispatchWorkItem.init(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
print("线程\(Thread.current)正在执行任务")
Thread.sleep(forTimeInterval: 2)
}
queue.async(group: group, execute: workitem)
workitem.wait()///这句代码很重要不加这句可能任务丢失
print("after waiting")
DispatchSemaphore 信号量
为了线程安全的统计数量,我们会使用信号量作计数。
原来的dispatch_semaphore_t现在用DispatchSemaphore对象表示。
初始化方法只有一个,传入一个Int类型的数。
let semaphore = DispatchSemaphore(value: 5)
/// 信号量减一 信号计数器为0时候卡()线程
semaphore.wait()
///信号量加一 信号计数器 + 1 同时也可以让卡住的线程继续运行
semaphore.signal()











网友评论