@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】:@synchronized
是thread safe
机制。在这个函数中编写的一段代码成为critical section
的一部分,一次只能执行一个线程。
@synchronize
隐式应用锁,而NSLock
显式应用它。
它只保证线程安全,不保证。我的意思是您为您的汽车聘请了一位专业的司机,但这并不能保证汽车不会发生事故。但是概率仍然很小。
【讨论】:
这绝对是错误的。 dispatch_once 与@syncrhonized 不一样,只能在单例分配下替代。以上是关于@synchronized() 作为目标 C 中的单例方法有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章
java面试题lock和synchronized有什么区别?