2009-08-01 35 views
6

我可以执行以下任何操作吗?他们会正确锁定/解锁同一个对象吗?为什么或者为什么不?假设有许多相同的线程使用全局变量“obj”,它在所有线程启动之前被初始化。更改@synchronized节中的锁定对象

1.

@synchronized(obj) { 
    [obj release]; 
    obj = nil; 
} 

2.

@synchronized(obj) { 
    obj = [[NSObject new] autorelease]; 
} 
+0

注意:http://stackoverflow.com/questions/1215330/ – 2009-08-01 04:31:53

+1

在阅读完所有贴子后,我决定调查@synchronized更彻底一点,并写一篇博客文章。您可能会觉得它很有用:http://rykap.com/objective-c/2015/05/09/synchronized.html – rjkaplan 2015-05-17 19:47:30

回答

8

简短的回答:不,他们将无法正常锁定/解锁,并且应该避免这样的方法。

我的第一个问题是为什么你想要这样做,因为这些方法首先无效使用@synchronized块的目的和好处。

在第二个示例中,一旦线程更改了obj的值,则到达@synchronized块的每个后续线程将同步新对象而不是原始对象。对于N个线程,您将显式创建N个自动释放对象,并且运行时可能会创建多达N个与这些对象相关的递归锁。换出临界区域内同步的对象是线程安全并发的基本禁忌。不要这样做。永远。如果多个线程可以同时安全地访问一个块,只需完全省略@synchronized。

在你的第一个例子中,结果可能是未定义的,当然也不是你想要的结果。如果运行时只使用对象指针来查找关联的锁,那么代码可以正常运行,但在我的简单测试中,nil上的同步没有可察觉的效果,所以您再次以无意义的方式使用@synchronized,因为它不提供任何保护。

我老实说不想苛刻,因为我认为你可能只是对构造好奇。我只是强烈地表达(希望)能够防止你和其他人编写有致命缺陷的代码,尤其是在假设它能够正确同步的情况下。祝你好运!