I guess @synchronized blocks are not object dependent but thread dependent...right? In that case why do we pass self?
A Synchronized block is a piece of code that can be used to perform synchronization on any specific resource of the method. A Synchronized block is used to lock an object for any shared resource and the scope of a synchronized block is smaller than the synchronized method.
A Java synchronized block doesn't allow more than one JVM, to provide access control to a shared resource. The system performance may degrade because of the slower working of synchronized keyword. Java synchronized block is more efficient than Java synchronized method.
The main purpose of synchronization is the sharing of resources without interference using mutual exclusion. The other purpose is the coordination of the process interactions in an operating system. Semaphores and monitors are the most powerful and most commonly used mechanisms to solve synchronization problems.
We need to synchronize the shared resources to ensure that at a time only one thread is able to access the shared resource. If an Object is shared by multiple threads then there is need of synchronization in order to avoid the Object's state to be getting corrupted. Synchronization is needed when Object is mutable.
I question this practice, as it is a known anti-pattern in other languages. The crux of the issue is that someone else could also synchronize
on your object, possibly causing deadlocks and other issues that would not have been present had you been using a private NSObject for the lock. For example:
@implementation foo
-(void) bar
{
@synchronized(self) {
@synchronized(sharedLock) {
//do something
}
}
}
Foo* foo = [[Foo alloc] init];
@synchronized(sharedLock) {
@synchronized(foo) {
//do something
}
}
//in another thread
[foo bar];
@synchronized
is a construct provided by the language to create synchronized scopes. As it would be highly inefficient to use a simple global shared mutex, and thus serializing every single @synchronized
scope in the application, the language allows us to specify a synchronization point.
Then it's up to the developer(s) to decide which synchronization points are appropriate for the task.
On an instance method, using self is common: the instance is the synchronization point. The @synchronized(self)
scope can be called on any number of instances, but only once for a given instance. Every @synchronized(self)
scope will be serialized for a given instance.
Of course, you are free to use another synchronization point if you want to do so. You can use the class (@synchronized(self.class)
) or anything else that suits your needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With