Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we pass self in @synchronized block?

I guess @synchronized blocks are not object dependent but thread dependent...right? In that case why do we pass self?

like image 528
Advaith Avatar asked Jul 26 '12 09:07

Advaith


People also ask

What is the purpose of synchronized block?

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.

Why synchronized block is better than 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.

Why do we need synchronization?

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.

Why is synchronization necessary in multithreaded programming?

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.


2 Answers

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];
like image 178
Ohad Schneider Avatar answered Oct 10 '22 00:10

Ohad Schneider


@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.

like image 39
fabrice truillot de chambrier Avatar answered Oct 10 '22 01:10

fabrice truillot de chambrier