简体   繁体   English

在目标c中等效于Java的并发哈希图

[英]Equivalent of java's concurrent hashmap in objective c

I have a NSMuableDictionary accessed by parallel threads,wherein few threads will be enumerating and few threads will be mutating.But we cant achieve this since 我有一个由并行线程访问的NSMuableDictionary ,其中将枚举几个线程,并且将变异几个线程。但是由于

"Collections cannot be mutated during enumeration" “不能在枚举期间对集合进行突变”

.Thought of using NSLock ,but then locking the dictionary till the enumeration completes will result in slow performance.In java we have concurrent hashmap which is smart enough to take care this scenario.Is there any better idea to achieve this in iOS ?.Please help. 。使用NSLock想法,但是将字典锁定直到枚举完成将导致性能降低。在Java中,我们有并发的hashmap,它足以应付这种情况。在iOS中有更好的主意吗?救命。

Read/Write access to Objective-C containers is generally not thread safe. 对Objective-C容器的读/写访问通常不是线程安全的。

You can solve the concurrency problem through associating the container to a dedicated dispatch queue, and then executing ALL read and write accesses on that queue. 您可以通过将容器关联到专用调度队列,然后对该队列执行所有读写访问来解决并发问题。 The queue can be either serial or concurrent. 队列可以是串行的,也可以是并发的。

You can invoke the following methods on any dedicated thread. 您可以在任何专用线程上调用以下方法。 However, I would suggest to switch your implementation to dispatch lib eventually. 但是,我建议最终将您的实现切换为调度lib。

Here, we create a serial queue: 在这里,我们创建一个串行队列:

dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", NULL);

Write access can be made asynchronously: 可以异步进行写访问:

- (void) addItem:(id)item forKey:(NSString*)key {
    dispatch_async(sync_queue, ^{
        [self.dict setObject:item forKey:key];
    });
}

Read access which returns a value must be synchronous: 返回值的读访问必须是同步的:

- (id) itemForKey:(NSString*)key {
     __block id item;
     dispatch_sync(sync_queue, ^{
         item = [self.dict objectForKey:key];
     });
     return item;
}

You can define similar wrappers for any task: 您可以为任何任务定义类似的包装器:

- (void) iterate {
    dispatch_async(sync_queue, ^{
        for (id item in self.dict) {
            ...
        }
    });
}

Using a concurrent queue: 使用并发队列:

dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", DISPATCH_QUEUE_CONCURRENT);

Write access can be made asynchronously and needs a barrier: 可以异步进行写访问,并且需要一个障碍:

- (void) addItem:(id)item forKey:(NSString*)key {
    dispatch_barrier_async(sync_queue, ^{
        [self.dict setObject:item forKey:key];
    });
}

Read access which returns a value must be synchronous, and it doesn't need a barrier. 返回值的读访问必须是同步的,并且不需要屏障。 Basically, there's no difference for synchronous and concurrent queues: 基本上,同步队列和并发队列没有区别:

- (id) itemForKey:(NSString*)key {
     __block id item;
     dispatch_sync(sync_queue, ^{
         item = [self.dict objectForKey:key];
     });
     return item;
}

There is no equivalent in objective-c, but you can avoid errors like "mutated while being enumerated" by holding elements in a temporary Array. 在objective-c中没有等效项,但是可以通过将元素保存在临时数组中来避免诸如“枚举时发生突变”之类的错误。 See this answer for more info. 有关更多信息,请参见此答案。

EDIT3: EDIT3:

This will do it: Implementing concurrent read exclusive write model with GCD 它将做到: 用GCD实现并发读取互斥写模型

Might still be some limitations, but at least you will have more fine-grained access and concurrent reads from several threads. 可能仍然会有一些限制,但是至少您将获得更细粒度的访问以及从多个线程的并发读取。

END EDIT 3: 结束编辑3:

Wrap the access to the dictionary in a class, and use @synchronized(self) {} in the access methods. 将对字典的访问包装在一个类中,并在访问方法中使用@synchronized(self){}。

EDIT2: Never mind. EDIT2: 没关系。 This will not give you what you want. 这不会给您您想要的。 Left the answer here as an antipattern. 将答案留在这里作为反模式。

EDIT: 编辑:

Something like this 像这样

(in your object implementation) (在您的对象实现中)

- (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