@synchronized()作为目标C中的单例方法做什么?


87

我刚刚创建了一个单例方法,我想知道该函数的功能@synchronized(),因为我经常使用它,但不知道其含义。

Answers:


119

它在代码块周围声明了一个关键部分。在多线程代码中,请@synchronized确保在任何给定时间,只有一个线程可以在块中执行该代码。

如果您不知道它的作用,那么您的应用程序可能不是多线程的,并且您可能不需要使用它(特别是如果单例本身不是线程安全的)。


编辑:添加了一些其他信息,这些信息不在2011年的原始答案中。

@synchronized伪指令可防止多个线程进入任何受引用同一对象@synchronized伪指令保护的代码区域。传递给@synchronized指令的对象是用作“锁”的对象。如果将不同的对象用作锁,则两个线程可以位于代码的同一受保护区域中,并且您也可以使用与锁相同的对象来保护两个完全不同的代码区域。

另外,如果你碰巧通过 nil作为锁定对象,则将根本不会采取任何锁定。


14
有两个要点:1)如果在其中使用nil指针,@synchronized则无济于事-您将失去保护。2)@synchronized
热门点击2013年

该答案具有误导性,不应被接受。尽管它说的有时是正确的(只要传递给synhronized的令牌在所有线程中都是同一对象),但它会误导不完整。同步会阻止同时执行任意数量的关联代码部分,而不仅仅是“块中的该代码”。要同步的参数有效地确定了哪些代码段(或答案称为“块”)可以防止并发访问。
Arda

@Arda你完全正确。我添加了更多信息,并提供了一些有关的Apple文档的链接@synchronized
约翰·卡尔斯贝克

@JohnCalsbeek,答案现在看起来好多了。我竖起大拇指。
阿达

@HotLicks有趣地指出了这一点,但最好还是简短地说一下替代方案(链接?)
itMaxence

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)吗?
2014年

甚至@synchronized(val, oldValue) { ... }
Valentin Shergin

我不确定我是否见过任何“完全线程安全”的方案。至少您需要知道您在做什么,而不仅仅是盲目地从某处复制代码。
Hot Licks 2015年

但是我想上面的代码毕竟是“完全线程安全的”,因为它绝对不起作用。
Hot Licks 2015年



-2

@synchronizedthread safe机制。写入此函数内部的一段代码成为的一部分critical section,一次只能执行一个线程。

@synchronize隐式地应用锁,而NSLock显式地应用锁。

它仅确保线程安全,而不能保证。我的意思是,您为汽车聘请了专业的驾驶员,但这仍然不能保证汽车不会发生事故。但是概率仍然是最小的。


2
这是绝对错误的。dispatch_once与@syncrhonized不同,仅在单例分配下才可以替代。
jugutier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.