无意翻了一下第三方代码:
- (void)setDidAddObjectBlock:(AWSTMMemoryCacheObjectBlock)block
{
__weak AWSTMMemoryCache *weakSelf = self;
dispatch_barrier_async(_queue, ^{
AWSTMMemoryCache *strongSelf = weakSelf;
if (!strongSelf)
return;
strongSelf->_didAddObjectBlock = [block copy];
});
}
- (AWSTMMemoryCacheObjectBlock)didRemoveObjectBlock
{
__block AWSTMMemoryCacheObjectBlock block = nil;
dispatch_sync(_queue, ^{
block = self->_didRemoveObjectBlock;
});
return block;
}
下面请看多读单写示例图dispatch_barrier_async ?? 陷入到我的知识盲区了,随后深入的了解并实现了一下
简单的说就是
:一个dispatch barrier 允许在一个并发队列中创建一个同步点。当在并发队列中遇到一个barrier, 他会延迟执行barrier的block,等待所有在barrier之前提交的blocks执行结束。 这时,barrier block自己开始执行。 之后, 队列继续正常的执行操作。这里指定的并发队列应该是自己通过dispatch_queue_create函数创建的。如果你传的是一个串行队列或者全局并发队列,这个函数等同于dispatch_async函数。
所有在barrier block之后提交的blocks会等到barrier block结束之后才执行
这特么简单么????
如果看不懂,详情介绍和实例请转:GCD学习总结(二)
好了不多bb
解释一下图:读取是可以并发的,就是说多条线程去读取数据不受限制可以并行,而这个写入操作就用上了
dispatch_barrier_async 栅栏函数
,这个函数的作用就是在它之前的读取操作执行完才能执行它,在它之后的读取操作必须等待它执行完(写入操作执行完)
才能执行。
下面给个实例:
let concurrentQueue = DispatchQueue.init(label: "concurrentQueue", attributes: .concurrent)
func begin(){
let key = "obj_key"
DispatchQueue.global().async {
let _:Any? = self.getObject(key: key)//读
}
DispatchQueue.global().async {
let _:Any? = self.getObject(key: key)//读
}
DispatchQueue.global().async {
let _:Any? = self.getObject(key: key)//读
}
DispatchQueue.global().async {
self.setObject(obj: "obj", key: key)//写
}
DispatchQueue.global().async {
let _:Any? = self.getObject(key: key)//读
}
DispatchQueue.global().async {
let _:Any? = self.getObject(key: key)//读
}
}
//写
func setObject(obj:Any, key:String){
concurrentQueue.async(flags: .barrier){
print("正在写入。。")
self.userCacheDic[key] = obj
}
}
//读
func getObject(key:String) -> Any?{
var obj:Any? = nil
concurrentQueue.sync {
obj = self.userCacheDic[key]
print("obj == \(String(describing: obj)) Thread == \(Thread.current)")
}
return obj
}
输出;
obj == nil Thread == <NSThread: 0x2812c0180>{number = 5, name = (null)}
obj == nil Thread == <NSThread: 0x2812c0180>{number = 5, name = (null)}
obj == nil Thread == <NSThread: 0x2812df000>{number = 3, name = (null)}
正在写入。。
obj == Optional("obj") Thread == <NSThread: 0x2812c0180>{number = 5, name = (null)}
obj == Optional("obj") Thread == <NSThread: 0x2812df000>{number = 3, name = (null)}
比较一下串行队列,使用barrier无疑比它效率更高
相关简书:
iOS GCD学习总结(一)
iOS GCD学习总结(二)
iOS 线程同步方案学习总结
信号量semaphore学习总结