Что делает @synchronized () как одноэлементный метод в цели C?


87

Я только что создал одноэлементный метод и хотел бы знать, что @synchronized()делает эта функция , поскольку я использую его часто, но не знаю смысла.

Ответы:


119

Он объявляет критическую секцию вокруг блока кода. В многопоточном коде @synchronizedгарантирует, что только один поток может выполнять этот код в блоке в любой момент времени.

Если вы не знаете, что оно делает, то ваше приложение, вероятно, не является многопоточным, и вам, вероятно, не нужно его использовать (особенно если сам синглтон не является потокобезопасным).


Изменить: добавление дополнительной информации, которой не было в исходном ответе от 2011 года.

@synchronizedДиректива предотвращает несколько потоков от входа любого участка кода , который защищен с помощью @synchronizedдирективы со ссылкой на тот же объект . Объект, переданный в @synchronizedдирективу, - это объект, который используется в качестве «блокировки». Два потока могут находиться в одной защищенной области кода, если в качестве блокировки используется другой объект, и вы также можете защищать две совершенно разные области кода, используя тот же объект, что и блокировка.

Кроме того, если вы проходите nilв качестве объекта блокировки, никакой блокировки не будет.


14
Пара важных моментов: 1) Если вы используете в нем нулевой указатель, @synchronizedон ничего не делает - вы остаетесь незащищенными. 2) @synchronizedработает медленно .
Hot Licks

Этот ответ вводит в заблуждение и не должен быть принятым ответом. Хотя то, что он говорит, иногда может быть правильным (пока токен, переданный в synhronized, является одним и тем же объектом во всех потоках), он вводит в заблуждение и является неполным. synchronized предотвращает одновременное выполнение любого количества связанных разделов кода, а не только «этого кода в блоке». Параметр synchronized эффективно определяет, какие разделы кода (или «блоки», как их называет ответ) защищены от одновременного доступа.
Arda

@Arda Вы совершенно правы. Я добавил немного больше информации и ссылку на документацию Apple по @synchronized.
John Calsbeek

@JohnCalsbeek, теперь ответ выглядит намного лучше. Большие пальцы вверх от меня.
Arda

@HotLicks интересно указать на это, но было бы даже лучше кратко сказать, какие могут быть альтернативы (ссылки?)
itMaxence 06

43

Из документации Apple здесь и здесь :

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

Документация предоставляет обширную информацию по этому вопросу. Стоит потратить время на его прочтение, особенно с учетом того, что вы использовали его, не зная, что он делает.


26

@synchronizedДиректива представляет собой удобный способ для создания мьютекс замки на лету в Objective-C код.

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

Синтаксис:

 @synchronized(key) 
 { 
  // thread-safe code 
 }

Пример:

 -(void)AppendExisting:(NSString*)val
{
  @synchronized (oldValue) {
      [oldValue stringByAppendingFormat:@"-%@",val];
  }
}

Теперь приведенный выше код является полностью потокобезопасным ... Теперь несколько потоков могут изменять значение.

Вышеупомянутое - всего лишь непонятный пример ...


3
Разве это не должно быть @synchronized (oldValue)?
Джоэл

Или даже @synchronized(val, oldValue) { ... }?
Валентин Шергин

Я не уверен, что когда-либо видел схему, которая была бы «совершенно потокобезопасной». По крайней мере, вам нужно знать, что вы делаете, а не просто слепо копировать откуда-то код.
Hot Licks

Но я полагаю, что приведенный выше код в конце концов «совершенно безопасен для потоков», поскольку он абсолютно ничего не делает.
Hot Licks

6

Блок @synchronized автоматически обрабатывает блокировку и разблокировку за вас . @synchronize у вас есть неявная блокировка, связанная с объектом, который вы используете для синхронизации. Вот очень информативное обсуждение этой темы, пожалуйста , следите за тем, как @synchronized lock / unlock в Objective-C?



-2

@synchronizedэто thread safeмеханизм. Часть кода, написанная внутри этой функции, становится частью critical section, в которой одновременно может выполняться только один поток.

@synchronize неявно применяет блокировку, тогда как NSLock применяет ее явно.

Это только обеспечивает безопасность потоков, но не гарантирует ее. Я имею в виду, что вы нанимаете для своей машины опытного водителя, но это не гарантирует, что машина не попадет в аварию. Однако вероятность остается ничтожной.


2
Это абсолютно неверно. dispatch_once НЕ делает то же самое, что и @syncrhonized, он может быть заменой ТОЛЬКО при выделении синглтона.
jugutier
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.