Ios 关于锁的困惑
关于锁,有一件事我不确定。我只读过一件我不确定的事;@synchronize(或者通常只是mutex)是否只保护代码的一部分(比如在一个方法中)或者作为一个整体锁定整个对象 例如,处理这些方法的两个线程修改数组Ios 关于锁的困惑,ios,multithreading,synchronization,nsmutablearray,mutex,Ios,Multithreading,Synchronization,Nsmutablearray,Mutex,关于锁,有一件事我不确定。我只读过一件我不确定的事;@synchronize(或者通常只是mutex)是否只保护代码的一部分(比如在一个方法中)或者作为一个整体锁定整个对象 例如,处理这些方法的两个线程修改数组 @synthesize m_myMutableArray; -(void)threadA { @synchronized(m_myMutableArray) { [m_myMutableArray removeAllObjects]; } } -(v
@synthesize m_myMutableArray;
-(void)threadA
{
@synchronized(m_myMutableArray) {
[m_myMutableArray removeAllObjects];
}
}
-(void)threadB
{
NSInteger asdf = 1;
@synchronized(m_myMutableArray) {
[m_myMutableArray addObject:asdf];
}
@synchronized没有做任何事情,是因为它们是两个独立的代码块,还是两个方法中锁定的是同一个互斥锁,这意味着m_myMutableArray是线程安全的
感谢同步@synchronized
的“参数”是一个所谓的令牌或密钥,因此您可以拥有不同的锁定部分。只有当它们拥有相同的令牌时,才会相互阻止。对象本身未“锁定”
因此,如果有两个@synchronized(foo)
和两个@synchronized(bar)
,foo部分会相互阻塞,但不会阻塞bar部分
如果可能,由于其动态特性,您应该这样做。同步的@synchronized
的“参数”是一个所谓的令牌或密钥,因此您可以有不同的锁定部分。只有当它们拥有相同的令牌时,才会相互阻止。对象本身未“锁定”
因此,如果有两个@synchronized(foo)
和两个@synchronized(bar)
,foo部分会相互阻塞,但不会阻塞bar部分
如果可能的话,你应该,由于其动态特性。相关:Kevin的回答也应该回答您的问题:只要m_myMutableArray指向的对象相同,它就是相同的互斥体。是否每次访问m_myMutableArray时都必须使用@synchronized指令?例如,如果threadB没有使用synchronized指令,如果threadA以前锁定了它,它还会阻止吗?是的,您应该在访问阵列时使用它。不,如果threadB没有使用
@synchronized
,它不会阻止threadA以前是否锁定它,这是有问题的,因为NSMutableArray
不是线程安全的。这意味着由于在多个位置使用了该阵列,因此会有相当多的锁定。如果threadA是主线程,我是否可以在threadB需要访问它时简单地使用performSelectorOnMainThread,它们会在同一个线程中排队并且是安全的吗?相关:Kevin的回答也应该回答你的问题:只要m_myMutableArray指向的对象是相同的,它就是相同的互斥体。是否每次访问该线程时都必须使用@synchronized指令m_myMutablearray?例如,如果threadB没有使用synchronized指令,如果threadA以前锁定了它,它还会阻止吗?是的,您应该在访问阵列时使用它。不,如果threadB没有使用@synchronized
,它不会阻止threadA以前是否锁定它,这是有问题的,因为NSMutableArray
不是线程安全的。这意味着由于在多个位置使用了该阵列,因此会有相当多的锁定。如果threadA是主线程,我是否可以在threadB需要访问它时简单地使用performSelectorOnMainThread,它们将在同一个线程中排队并且是安全的?如果threadA是主线程,我是否可以对threadB中的所有干扰操作使用performSelectorOnMainThread?你的意思是,避免完全锁定?这取决于您想要做什么,这是一个选项。但请注意,如果设置waituntldone:YES,threadB将阻塞,直到main完成其当前运行循环迭代,然后可以执行选择器。大部分时间比锁定慢。如果我不等待完成(这是回调更新UI元素,如ListView),这是一个好的解决方案吗?是的,没问题。我也经常这样做。如果threadA是主线程,我可以对threadB中的所有干扰操作使用performSelectorOnMainThread吗?你的意思是,避免完全锁定?这取决于您想要做什么,这是一个选项。但请注意,如果设置waituntldone:YES,threadB将阻塞,直到main完成其当前运行循环迭代,然后可以执行选择器。大部分时间比锁定慢。如果我不等待完成(这是回调更新UI元素,如ListView),这是一个好的解决方案吗?是的,没问题。我也经常这样做。