我对线程安全有问题。我有一个队列,当我修改内容时,会导致线程间的错误。我以前没用过锁,但我想我试过了。我在所有操纵队列的nsmutablearray的代码周围添加了一个锁。我认为,问题是我没有为所有的人使用相同的锁。我在每个修改数组的方法中创建了nslock的新实例。我想我应该用一个nslock ivar来保护阵列。但我的困惑来自这样一个事实:一旦我添加了它,它就会起作用。下面是一个样本。我想无论我在哪里创建了一个新的nslock,我都应该只使用一个ivar nslock。我认为这段代码只是针对其他队列锁定了队列,针对其他队列锁定了队列,而不是针对队列锁定了队列。澄清一下就好了。

@implmentation

...

- (void)enqueue:(id)obj
{
  NSLock *arrayLock = [[NSLock alloc] init];
  [arrayLock lock];
   [_backingStore addObject:obj];
  [arrayLock unlock];
}

- (id)dequeue
{
  NSLock *arrayLock = [[NSLock alloc] init];
  [arrayLock lock];
  id result = [_backingStore firstObject];

  if( result )
  {
    [_backingStore removeObjectAtIndex:0];
  }

  [arrayLock unlock];
  return result;
}

...

@end

最佳答案

是的,您确实需要使用相同的nslock实例来锁定对数组的两个访问。与许多多线程错误一样,由于添加了额外的代码而导致的时间差异,该问题似乎已经消失。或者,可能只是你运气不好,第二次测试时问题没有出现。
不管有什么价值,nslock只是objective-c中锁定关键部分访问权限的一种方法。从代码复杂性的角度来看,也可以使用@synchronized()这可能更容易:

@synchronized(someSharedToken) {
    // Do your array access here
}

您还可以使用串行调度队列来序列化对资源的访问。这有几个优点,其中最重要的是能够在不等待当前线程完成工作的情况下将工作分派给它。将工作分派到队列中的成本也低于取出锁的成本。请参阅Apple并发编程指南的Creating Serial Dispatch Queues部分。

10-04 12:56