Question

I know what @synchronized() does, but...
sometimes we have:

1- @synchronized(self)
2- @synchronized([MyClass class])
3- @synchrinized(myObj)

What is the difference, and what is the parameter I should pass to this block ?

Was it helpful?

Solution

From the documentation:

The object passed to the @synchronized directive is a unique identifier used to distinguish the protected block. If you execute the preceding method in two different threads, passing a different object for the anObj parameter on each thread, each would take its lock and continue processing without being blocked by the other. If you pass the same object in both cases, however, one of the threads would acquire the lock first and the other would block until the first thread completed the critical section.

So it depends on what you want to protect from being executed simultaneously, and there are applications for all three cases.

For example, in

-(void)addToMyArray1:(id)obj
{
    @synchronized(self) {
        [self.myArray1 addObject:obj];
    }
}

-(void)addToMyArray2:(id)obj
{
    @synchronized(self) {
        [self.myArray2 addObject:obj];
    }
}

both @synchronized blocks cannot be executed simultaneously by two threads calling the method on the same instance (self), thus protecting simultaneous access to the arrays from different threads.

But it also prevents the block from the first method to be executed simultaneously executed with the block from the second method, because they use the same lock self. Therefore, for more fine-grained locking, you could use different locks:

-(void)addToMyArray1:(id)obj
{
    @synchronized(self.myArray1) {
        [self.myArray1 addObject:obj];
    }
}

-(void)addToMyArray2:(id)obj
{
    @synchronized(self.myArray2) {
        [self.myArray2 addObject:obj];
    }
}

Now the simultaneous access to self.myArray1 and self.myArray2 from different threads is still protected, but independently of each other.

A lock on the class can be used to protect access to a global variable. This is just a trivial example for demonstration purposes:

static int numberOfInstances = 0;

-(id)init
{
    self = [super init];
    if (self) {
        @synchronized([self class]) {
            numberOfInstances++;
        }
    }
}

OTHER TIPS

@synchronized should have the same object passed each time. So @synchronized(self) would work best.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top