@synchronized 会阻塞整个线程吗
Posted
技术标签:
【中文标题】@synchronized 会阻塞整个线程吗【英文标题】:Does @synchronized block a whole thread 【发布时间】:2012-05-21 09:27:42 【问题描述】:说你愿意
MyLock *lock = [[MyLock new] autorelease];
@synchronized(lock)
NSLog(@"Hello World");
//some very long process
在主线程中。这是否意味着直到//一些非常长的过程完成,主线程被锁定?如果有其他线程调用
//Update on the main thread
dispatch_sync(dispatch_get_main_queue(), ^
//Do some updates
);
有些更新永远不会被调用?我说的对吗?
【问题讨论】:
【参考方案1】:如果第一个代码 sn-p 中的代码从未完成,则不会调用第二个代码,无论 @synchronized
语句如何。该线程被您正在执行的代码阻塞。 @synchronized
语句用于同步多个线程之间的数据访问,它要求所有参与的线程实际使用该语句。它不会“神奇地”锁定对数据结构的访问,除非所有参与线程“同意”它。
您不要使用@synchronized
来确保在给定(单个)线程上只执行一个方法,无论如何都是这样。
为了给你一个具体的使用例子,假设你有一个NSMutableArray
,你想防止它同时被不同的线程修改(这可能导致数据损坏)。在这种情况下,您始终可以使用相同的锁定令牌在 @synchronized
块中访问它。
例子:
//Thread 1:
@synchronized (myArray)
[myArray addObject:@"foo"];
//Thread 2:
@synchronized (myArray)
[myArray removeObjectAtIndex:0];
这将确保@synchronized
所包含的代码块永远不会同时执行。当一个线程进入块时,其他线程会一直等待直到它完成,但只有在它们也使用相同的@synchronized
语句。如果您忘记在一个线程上使用它,那么如果您在另一个线程上使用它就没有任何帮助。
【讨论】:
【参考方案2】:简短的回答是否定的。我认为您不了解锁定的概念。您应该在这里阅读更多关于同步的信息:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html
当您访问您试图保护的代码时,您必须在每种情况下使用相同的锁定对象(相同的实例!)进行同步。您可以将锁定对象存储为类的属性。
在你的情况下:
self.lock = [[MyLock new] autorelease]; //in init method initialize retain or strong lock property
...
@synchronized(self.lock)
NSLog(@"Hello World");
//some very long process
//Update on the main thread
dispatch_sync(dispatch_get_main_queue(), ^
@synchronized(self.lock)
NSLog(@"Hello World");
//some very long process
);
如果您可以用作锁定对象,您正在尝试保护的对象。
【讨论】:
以上是关于@synchronized 会阻塞整个线程吗的主要内容,如果未能解决你的问题,请参考以下文章