1
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 Answers1

2

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()
    }
  }
}
Juraj Blahunka
  • 17,913
  • 6
  • 34
  • 52
  • 1. Does a simple lock work? I am a bit confuses if the way you are proposing actually locks the resource. Should the lock go to the getter of the property? 2. Does lock need to exist to every place this resource is accessed? Or using it only in modify does lock it for everybody? – George Termentzoglou Mar 18 '21 at 14:08
  • So to rephrase my question. Lock doesnt lock resources, it locks code block lines, right? Wrapping lock around a resource doen’t lock the resource everywhere – George Termentzoglou Mar 18 '21 at 14:11
  • Correct, to synchronize access to the `localSharedResource`, it needs to be wrapped either by the locking code or via a serial queue. This needs to happen every time `localSharedResource` is accessed or modified. – Juraj Blahunka Mar 19 '21 at 09:40