shweta
shweta

Reputation: 1

@synchronized(self) block at multiple places for multiple resources in multithreaded environment , objective c

Does locking in one function from a thread, blocks all other thread trying to acquire the lock in different functions.

We can use gcd for accessing the critical sections mentioned below, just wanted to know how @synchronized(self) works. For ex.

Do multiple threads with ONLY writeString() calls gets blocked when the execution is in @synchronized(self){ } in writeString()?

OR all the threads calling the functions of the same class with @synchronized(self){} (e.g.readDataFromFile()) gets blocked when execution is in @synchronized(self){ } in writeString() ?

-(void)writeString:(NSString*)string forObj:(id)obj 
{
    @synchronized(self)
    {
        [obj write:string];
    }
}

-(void)readDataFromFile:(NSString*)file
{
    @synchronized(self)
    {
        [self read];
    }
}

Upvotes: 0

Views: 253

Answers (2)

Teknein
Teknein

Reputation: 106

So for this one, we need to zoom out to a bit of a larger context.

In the case where you have two instances:

YourClass *a = [[YourClass alloc] init];
YourClass *b = [[YourClass alloc] init];

a will sync access to both methods for itself.
b will sync access to both methods for itself.

So for instance, concurrently from two different threads, a and b can both run -writeString:forObj: at the same time without blocking.

Now if you changed the implementation to use @synchronized(self.class) that entirely changes the game. Rather than syncing on the 'instance', you would be syncing on the 'class' as a whole, so every instance would have to sync access to the methods.

So for instance using the use @synchronized(self.class) implementation, concurrently from two different threads, if a and b both run -writeString:forObj: at the same time, that would then serialize those calls so only one runs while the other is blocked waiting for the sync to unlock.

I hope that clarifies the difference between locking on an instance of a class vs locking every instance for a given class.

Edit: May also be worth noting, if you use @synchronized(self) in a 'class' method like the following:

// implementation of 'ExampleClass'
+(void)serializeWriting:(NSString*)string toObj:(id)obj {
    @synchronized(self) {
        [obj write:string];
    }
}

That also changes the game, so anytime that method is called, its synced against the class itself, so something like [ExampleClass serializeWriting:@"some string" toObj:somethingElse] would only ever run the critical section [obj write:string] on a single thread no matter how many places/threads it was called from.

Upvotes: 0

bbum
bbum

Reputation: 162712

@synchronized(A) can be thought of as a lock where A identifies the lock to use.

If you pass the same value for A into two calls to @synchronized(), then they'll use the same lock and be exclusive. If you pass two different values for two calls, then they will not be exclusive.

Upvotes: 1

Related Questions