簡體   English   中英

在目標c中等效於Java的並發哈希圖

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM