Does DispatchQueue also Lock the resources used inside it?

629 Views Asked by At
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()
    }
  }
}

Should I use lock if localSharedResource is accessed by other threads too?

1

There are 1 best solutions below

3
On

It depends.

If all access to localSharedResource is wrapped via a localQueue.sync or localQueue.async, then the threadLock property can be removed. The serial queue (localQueue) is already doing all the necessary synchronization. The above could be rewritten as:

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

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

If however there are multiple threads potentially accessing the localSharedResource and localQueue is one of them, then the localSharedResource needs to have additional means of synchronization. Either by an NSLock or by using a dedicated serial queue.

E.g.

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