[英]Equivalent of java's concurrent hashmap in objective c
我有一個由並行線程訪問的NSMuableDictionary
,其中將枚舉幾個線程,並且將變異幾個線程。但是由於
“不能在枚舉期間對集合進行突變”
。使用NSLock
想法,但是將字典鎖定直到枚舉完成將導致性能降低。在Java中,我們有並發的hashmap,它足以應付這種情況。在iOS
中有更好的主意嗎?救命。
對Objective-C容器的讀/寫訪問通常不是線程安全的。
您可以通過將容器關聯到專用調度隊列,然后對該隊列執行所有讀寫訪問來解決並發問題。 隊列可以是串行的,也可以是並發的。
您可以在任何專用線程上調用以下方法。 但是,我建議最終將您的實現切換為調度lib。
dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", NULL);
可以異步進行寫訪問:
- (void) addItem:(id)item forKey:(NSString*)key {
dispatch_async(sync_queue, ^{
[self.dict setObject:item forKey:key];
});
}
返回值的讀訪問必須是同步的:
- (id) itemForKey:(NSString*)key {
__block id item;
dispatch_sync(sync_queue, ^{
item = [self.dict objectForKey:key];
});
return item;
}
您可以為任何任務定義類似的包裝器:
- (void) iterate {
dispatch_async(sync_queue, ^{
for (id item in self.dict) {
...
}
});
}
dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", DISPATCH_QUEUE_CONCURRENT);
可以異步進行寫訪問,並且需要一個障礙:
- (void) addItem:(id)item forKey:(NSString*)key {
dispatch_barrier_async(sync_queue, ^{
[self.dict setObject:item forKey:key];
});
}
返回值的讀訪問必須是同步的,並且不需要屏障。 基本上,同步隊列和並發隊列沒有區別:
- (id) itemForKey:(NSString*)key {
__block id item;
dispatch_sync(sync_queue, ^{
item = [self.dict objectForKey:key];
});
return item;
}
在objective-c中沒有等效項,但是可以通過將元素保存在臨時數組中來避免諸如“枚舉時發生突變”之類的錯誤。 有關更多信息,請參見此答案。
EDIT3:
它將做到: 用GCD實現並發讀取互斥寫模型
可能仍然會有一些限制,但是至少您將獲得更細粒度的訪問以及從多個線程的並發讀取。
結束編輯3:
將對字典的訪問包裝在一個類中,並在訪問方法中使用@synchronized(self){}。
EDIT2: 沒關系。 這不會給您您想要的。 將答案留在這里作為反模式。
編輯:
像這樣
(在您的對象實現中)
- (void) setObjectSynchronized:(id) value forKey:(id) key {
@synchronized(self) {
[self.internalDictionary setObject:value forKey:key];
}
}
- (void) objectForKeySynchronized:(id) key {
@synchronized(self) {
return [self.internalDictionary objectForKey:key];
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.