Reputation: 1
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
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
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