更改@synchronized部分内的锁定对象

时间:2009-08-01 03:30:55

标签: objective-c synchronization

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

1

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

2

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

1 个答案:

答案 0 :(得分:9)

简短回答:不,他们不会正确锁定/解锁,应该避免这种方法。

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

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

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

老实说,我并不是想要苛刻,因为我觉得你可能只是对这个结构感到好奇。我只是强烈地措辞(希望)阻止你和其他人编写具有致命缺陷的代码,特别是如果假设它正确同步的话。祝你好运!