無意翻了一下第三方代碼:
- (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 ?? 陷入到我的知識盲區(qū)了辛辨,隨后深入的了解并實現(xiàn)了一下
簡單的說就是
:一個dispatch barrier 允許在一個并發(fā)隊列中創(chuàng)建一個同步點。當在并發(fā)隊列中遇到一個barrier, 他會延遲執(zhí)行barrier的block,等待所有在barrier之前提交的blocks執(zhí)行結束够挂。 這時亥鸠,barrier block自己開始執(zhí)行百拓。 之后泥彤, 隊列繼續(xù)正常的執(zhí)行操作衔沼。這里指定的并發(fā)隊列應該是自己通過dispatch_queue_create函數(shù)創(chuàng)建的蝌借。如果你傳的是一個串行隊列或者全局并發(fā)隊列昔瞧,這個函數(shù)等同于dispatch_async函數(shù)。
所有在barrier block之后提交的blocks會等到barrier block結束之后才執(zhí)行
這特么簡單么菩佑?自晰??稍坯?
如果看不懂酬荞,詳情介紹和實例請轉:GCD學習總結(二)
好了不多bb
解釋一下圖:讀取是可以并發(fā)的,就是說多條線程去讀取數(shù)據(jù)不受限制可以并行瞧哟,而這個寫入操作就用上了
dispatch_barrier_async 柵欄函數(shù)
混巧,這個函數(shù)的作用就是在它之前的讀取操作執(zhí)行完才能執(zhí)行它,在它之后的讀取操作必須等待它執(zhí)行完(寫入操作執(zhí)行完)
才能執(zhí)行勤揩。
下面給個實例:
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學習總結