首页 > 解决方案 > DispatchQueue 是否也锁定了里面使用的资源?

问题描述

class Factory {
  var localSharedResource
  var localQueue =  DispatchQueue(label: "localQueue")
  let threadLock = NSLock()

  func modify(){
    localQueue.async {
      self.threadLock.lock() 
      localSharedResource = "a change is made here"
      self.threadLock.unlock()
    }
  }
}

如果 localSharedResource 也被其他线程访问,我应该使用 lock 吗?

标签: swiftthread-safetydispatch-queuenslock

解决方案


这取决于。

如果所有访问localSharedResource都通过localQueue.syncor包装localQueue.async,则threadLock可以删除该属性。串行队列 ( localQueue) 已经在进行所有必要的同步。上式可以改写为:

class Factory {
  var localSharedResource
  var localQueue =  DispatchQueue(label: "localQueue")

  func modify(){
    localQueue.async {
      localSharedResource = "a change is made here"
    }
  }
}

然而,如果有多个线程可能访问localSharedResource并且localQueue是其中之一,那么localSharedResource需要有额外的同步方式。通过NSLock或使用专用串行队列。

例如

class Factory {
  var localSharedResource
  var localQueue =  DispatchQueue(label: "localQueue")
  let threadLock = NSLock()

  func modify(){
    localQueue.async {
      self.threadLock.lock() 
      localSharedResource = "a change is made here"
      self.threadLock.unlock()
    }
  }
  
  func modifyAgain() {
    DispatchQueue.global().async {
      self.threadLock.lock()
      localSharedResource = "another change"
      self.threadLock.unlock()
    }
  }
}

推荐阅读