1

My understanding of the @synchronized(obj) { ... } directive in Objective-C is that it's essentially the same as the lock(obj) { ... } construct in C#, i.e...

  • Both create a kind of local, anonymous mutex tied to the specified object
  • Any thread entering the @synchronized/lock block must acquire that mutex prior to executing any code in the block (and will wait to acquire the mutex before proceeding if it's already reserved).

In C#, using lock(this) is strongly discouraged (see Why is lock(this) {...} bad?) for an example), basically because you then have no control over who locks your mutex or when (since someone else could be using your object as a mutex).

I assumed that concept this would also apply to @synchronized(self) in Objective-C, but I was told by a senior developer on my team that @synchronized functions differently than lock, and the concerns in the above SO post don't apply.

I guess my question is - what am I misunderstanding about @synchronized? Why is @synchronized(self) safe when lock(this) is not?

Thanks.

Community
  • 1
  • 1
Chris Vig
  • 8,552
  • 2
  • 27
  • 35
  • This point is raised [in an old post here about `@synchronized()`](http://stackoverflow.com/a/29218157/603977). – jscs Oct 22 '15 at 22:42

1 Answers1

0

There are different attitudes to things. I had a quick look at the C# answer that you linked to, and if you did the same things with @synchronized, you would be crucified. You should use @synchronized for the absolutely minimum amount of time, and you should absolutely not call anything else that could use @synchronized at the same time. Obey this rule, and you are fine. I suppose in C# you would be just as fine, but in C# they assume that others do stupid things.

There's a simple strategy to avoid deadlocks (if you follow it): Have a set of "level 0" locks: While you hold a "level 0" lock you must not try to acquire any other locks. Then you have a set of "level 1" locks: While you hold a "level 1" lock you can acquire a "level 0" lock, but nothing else. And so on: If you hold a "level n" lock, you may acquire locks at a lower level, but none at the same or higher level. Voila: No deadlocks possible.

A @synchronized that is not at level 0 would be very rare, and you should think very hard about it. There are other synchronisation mechanisms, like serial queues, that work just fine as well.

gnasher729
  • 51,477
  • 5
  • 75
  • 98