繁体   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