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