Я думаю, что @синхронизированные блоки не зависят от объекта, а зависят от потока... правильно? В этом случае, почему мы передаем себя?
Почему мы передаем себя в блоке @synchronized?
Ответ 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];