在我们的应用程序中,我们在几个位置使用单例,最近我完成了在所有单例方法中添加@synchronized命令,以确保它们是线程安全的。我的问题是,把这称为“这样”有什么区别:
+ (RLReceiver *) getReceiver
{
static RLReceiver *receiverCache;
@synchronized(receiverCache)
{
if (!receiverCache )
receiverCache = [[RLReceiver alloc] init];
return receiverCache;
}
}在本例中,我同步了类RLReceiver的静态实例,但我也看到(编译器出人意料地允许)这样做:
+ (RLReceiver *) getReceiver
{
static RLReceiver *receiverCache;
@synchronized(self)
{
if (!receiverCache )
receiverCache = [[RLReceiver alloc] init];
return receiverCache;
}
}同步在self上的位置。这让我有点困惑,因为这个方法是一个类方法,而且在这个方法的范围内甚至不应该有一个self。有人能解释一下静态变量和自我在这个上下文中的区别,以及类方法中的自我是如何存在的吗?
发布于 2015-01-30 18:23:18
Apple说:“传递给@ same指令的对象是一个唯一的标识符,用于区分受保护的块。如果您在两个不同的线程中执行前面的方法,为每个线程上的anObj参数传递一个不同的对象,每个线程都将取其锁并继续处理,而不会被另一个线程阻塞。但是,如果在这两种情况下都传递相同的对象,那么其中一个线程将首先获得锁,而另一个线程将阻塞,直到第一个线程完成关键部分。”
// Apple示例:
- (void)myMethod:(id)anObj
{
@synchronized(anObj)
{
// Everything between the braces is protected by the @synchronized directive.
}
}在你的例子中,辣妹说问题是第一次发射。您的对象在第一次启动时不存在,同步也不能正常工作。如果你尝试:
1
+(RLReceiver *) getReceiver
{
static RLReceiver *receiverCache;
@synchronized(receiverCache)
{
if (!receiverCache ) {
receiverCache = [[RLReceiver alloc] init];
}
for (int i=0; i<100; i++) {
NSLog(@"Numbers in order i %i",i);
}
return receiverCache;
}
} 和2
+ (RLReceiver *) getReceiver
{
static RLReceiver *receiverCache;
@synchronized(self)
{
if (!receiverCache ) {
receiverCache = [[RLReceiver alloc] init];
}
for (int i=0; i<100; i++) {
NSLog(@"Numbers in order i %i",i);
}
return receiverCache;
}
}来自第一次调用的另一个对象,类似于:
dispatch_async(dispatch_queue_create("OtherQueue", 0), ^{
RLReceiver *rece= [RLReceiver getReceiver];
});
RLReceiver *receSorF = [RLReceiver getReceiver];您可以看到,在1种情况下,数字是如何混合的,并且同步是如何工作的。在2种情况下,一位伯爵等待另一位伯爵。
当我们同步已存在的对象中的代码时,我们可以使用该对象,在其他情况下是类名。
谢谢@HotLick。
https://stackoverflow.com/questions/28242063
复制相似问题