Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@synchronized block versus GCD dispatch_async()

Essentially, I have a set of data in an NSDictionary, but for convenience I'm setting up some NSArrays with the data sorted and filtered in a few different ways. The data will be coming in via different threads (blocks), and I want to make sure there is only one block at a time modifying my data store.

I went through the trouble of setting up a dispatch queue this afternoon, and then randomly stumbled onto a post about @synchronized that made it seem like pretty much exactly what I want to be doing.

So what I have right now is...

// a property on my object
@property (assign) dispatch_queue_t matchSortingQueue;

// in my object init
_sortingQueue = dispatch_queue_create("com.asdf.matchSortingQueue", NULL);

// then later...
- (void)sortArrayIntoLocalStore:(NSArray*)matches
{
    dispatch_async(_sortingQueue, ^{
      // do stuff...
    });
}

And my question is, could I just replace all of this with the following?

- (void)sortArrayIntoLocalStore:(NSArray*)matches
{
    @synchronized (self) {
      // do stuff...
    };
}

...And what's the difference between the two anyway? What should I be considering?

like image 668
livingtech Avatar asked Feb 06 '13 05:02

livingtech


1 Answers

Although the functional difference might not matter much to you, it's what you'd expect: if you @synchronize then the thread you're on is blocked until it can get exclusive execution. If you dispatch to a serial dispatch queue asynchronously then the calling thread can get on with other things and whatever it is you're actually doing will always occur on the same, known queue.

So they're equivalent for ensuring that a third resource is used from only one queue at a time.

Dispatching could be a better idea if, say, you had a resource that is accessed by the user interface from the main queue and you wanted to mutate it. Then your user interface code doesn't need explicitly to @synchronize, hiding the complexity of your threading scheme within the object quite naturally. Dispatching will also be a better idea if you've got a central actor that can trigger several of these changes on other different actors; that'll allow them to operate concurrently.

Synchronising is more compact and a lot easier to step debug. If what you're doing tends to be two or three lines and you'd need to dispatch it synchronously anyway then it feels like going to the effort of creating a queue isn't worth it — especially when you consider the implicit costs of creating a block and moving it over onto the heap.

like image 190
Tommy Avatar answered Sep 19 '22 17:09

Tommy