@synchronized() 作为目标 C 中的单例方法有啥作用?

Posted

技术标签:

【中文标题】@synchronized() 作为目标 C 中的单例方法有啥作用?【英文标题】:What does @synchronized() do as a singleton method in objective C?@synchronized() 作为目标 C 中的单例方法有什么作用? 【发布时间】:2011-06-11 18:55:11 【问题描述】:

刚刚创建了一个单例方法,想知道@synchronized()这个函数是干什么的,经常用,但是不知道是什么意思。

【问题讨论】:

【参考方案1】:

它在代码块周围声明了一个critical section。在多线程代码中,@synchronized 保证在任何给定时间只有一个线程可以在块中执行该代码。

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


编辑:添加一些 2011 年原始答案中没有的更多信息。

@synchronized 指令 prevents multiple threads from entering any region of code that is protected by a @synchronized directive referring to the same object。传递给@synchronized 指令的对象是用作“锁”的对象。如果使用不同的对象作为锁,两个线程可以在同一个受保护的代码区域中,您也可以使用相同的对象作为锁来保护两个完全不同的代码区域。

另外,如果你碰巧将nil作为锁定对象传递,则根本不会获得任何锁定。

【讨论】:

几个要点: 1) 如果你在@synchronized 中使用一个nil 指针,它什么也不做——你没有受到保护。 2) @synchronized 此答案具有误导性,不应成为公认的答案。尽管它所说的有时是正确的(只要传递给 synhronized 的令牌在所有线程中都是同一个对象),但它是不完整的误导性的。 同步 防止任何数量的关联代码段同时执行,而不仅仅是“块中的代码”。 synchronized 的参数有效地确定了哪些代码段(或答案称之为“块”)免受并发访问。 @Arda 你完全正确。我添加了更多信息和一些关于 @synchronized 的 Apple 文档的链接。 @JohnCalsbeek,现在的答案看起来好多了。向我竖起大拇指。 @HotLicks 指出这一点很有趣,但最好简单地说一下可能的替代方案(链接?)【参考方案2】:

来自 Apple 文档 here 和 here:

@synchronized 指令是一个 创建互斥锁的便捷方法 在 Objective-C 代码中运行。这 @synchronized 指令做什么 其他互斥锁会做——它可以防止 不同的线程从获取 同一个锁。

文档提供了有关此主题的大量信息。值得花时间阅读它,尤其是考虑到您一直在使用它而不知道它在做什么。

【讨论】:

【参考方案3】:

@synchronized 指令是在 Objective-C 代码中动态创建互斥锁的便捷方式。

@synchronized 指令做了任何其他互斥锁会做的事情——它防止不同的线程同时获取同一个锁。

语法:

 @synchronized(key) 
  
  // thread-safe code 
 

例子:

 -(void)AppendExisting:(NSString*)val

  @synchronized (oldValue) 
      [oldValue stringByAppendingFormat:@"-%@",val];
  

现在上面的代码是完全线程安全的。现在多个线程可以改变值。

以上只是一个不起眼的例子……

【讨论】:

不应该是@synchronized(oldValue) 吗? 甚至@synchronized(val, oldValue) ... ? 我不确定我是否见过任何“完全线程安全”的方案。至少你需要知道自己在做什么,而不是盲目地从某个地方复制代码。 但我想上面的代码毕竟是“完全线程安全的”,因为它什么也没做。【参考方案4】:

@synchronized 块会自动为您处理锁定和解锁。 @同步 您有一个与您用于同步的对象关联的隐式锁。这是关于这个主题的非常丰富的讨论,请关注How does @synchronized lock/unlock in Objective-C?

【讨论】:

【参考方案5】:

这里的答案很好:

Help understanding class method returning singleton

进一步解释创建单例的过程。

【讨论】:

【参考方案6】:

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

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

它只保证线程安全,不保证。我的意思是您为您的汽车聘请了一位专业的司机,但这并不能保证汽车不会发生事故。但是概率仍然很小。

【讨论】:

这绝对是错误的。 dispatch_once 与@syncrhonized 不一样,只能在单例分配下替代。

以上是关于@synchronized() 作为目标 C 中的单例方法有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

java面试题lock和synchronized有什么区别?

synchronized将任意对象作为对象监视器

在目标 C 中归档多个对象并将它们作为对象数组取消归档

synchronized的原理

目标 c 中的 XCTKVOExpectation 使用示例

Synchronized