Подтвердить что ты не робот

Почему мы передаем себя в блоке @synchronized?

Я думаю, что @синхронизированные блоки не зависят от объекта, а зависят от потока... правильно? В этом случае, почему мы передаем себя?

4b9b3361

Ответ 1

@synchronized - это конструкция, предоставляемая языком для создания синхронизированных областей. Поскольку было бы крайне неэффективно использовать простой глобальный общий мьютекс и таким образом сериализовать каждую отдельную область @synchronized в приложении, язык позволяет нам указать точку синхронизации.

Затем разработчику (разработчикам) нужно решить, какие точки синхронизации подходят для задачи.

В методе экземпляра используется self: экземпляр - это точка синхронизации. Область @synchronized(self) может быть вызвана для любого количества экземпляров, но только один раз для данного экземпляра. Каждая область @synchronized(self) будет сериализована для данного экземпляра.

Конечно, вы можете использовать другую точку синхронизации, если хотите это сделать. Вы можете использовать класс (@synchronized(self.class)) или что-нибудь еще, что соответствует вашим потребностям.

Ответ 2

Объект, переданный в, используется для того, чтобы различать, какие блоки @synchronized соответствуют блокировке друг друга. Использование self часто бывает удобным, но иногда полезно использовать какой-либо другой объект, если вы хотите только синхронизировать меньшие, более конкретные разделы кода (например, синхронизировать весь доступ к определенному NSMutableDictionary, а не синхронизировать все в весь экземпляр)

Я не уверен, что вы подразумеваете под "зависящим от потока". Цель @synchronized - это блоки кода, которые могут выполняться на разных потоках, и вам нужно обеспечить только 1 запуск в любое время без перекрытия. Важно для выполнения действий, которые не являются потокобезопасными (например, мутирующие коллекции).

Ответ 3

Я сомневаюсь в этой практике, так как это известный анти-шаблон на других языках. Суть проблемы в том, что кто-то еще мог synchronize на вашем объекте, возможно, вызывая взаимоблокировки и другие проблемы, которые бы не присутствовали, если бы вы использовали частный NSObject для блокировки. Например:

@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];