多线程同步加锁主要方式有3种:NSLock(普通锁)、NSCondition(状态锁)、synchronized同步代码块
还有少用的NSRecursiveLock(递归锁)、NSConditionLock(条件锁)、NSDistributedLock(分布锁)。
- (void)lock; //加锁
- (void)unlock; //解锁
- (void)wait; //睡眠等待解锁
- (BOOL)waitUntilDate:(NSDate *)limit; //定时等待解锁
- (void)signal; //加锁信号
区别:
NSLock和NSCondition都实现<NSLocking>协议;而synchronized(锁){….}采用同步加锁的方式实现加锁,只要锁是唯一的就可以,一般设置锁为当前对象或者类名。NSLock和NSCondition是显式加锁,synchronized同步代码块是隐式加锁。
协议如下:
@protocol NSLocking
- (void)lock; //加锁
- (void)unlock; //解锁
@end
详解介绍NSLock:<NSLocking>-------------普通锁
<1>属性:@property (copy) NSString *name //锁的名字
<2>其他方法:
- (BOOL)tryLock; //尝试加锁(有可能已经被其他线程加锁)
- (BOOL)lockBeforeDate:(NSDate *)limit; //定时加锁
详解介绍NSCondition:<NSLocking>---------状态锁
<1>属性:@property (copy) NSString *name //锁的名字
<2>其他方法:
- (BOOL)waitUntilDate:(NSDate *)limit; //定时等待解锁
- (void)signal; //加锁信号
- (void)broadcast; //解锁通知
详解介绍NSRecursiveLock:<NSLocking>------ 递归锁
<1>属性:@property (copy) NSString *name //锁的名字
<2>其他方法:
- (BOOL)tryLock; //尝试加锁(有可能已经被其他线程加锁,此时无法在加锁)
- (BOOL)lockBeforeDate:(NSDate *)limit; //定时加锁
详解介绍NSConditionLock:<NSLocking>------条件锁
<1>属性:@property (copy) NSString *name //锁的名字
@property (readonly) NSInteger condition; //状态
<2>其他方法:
- (BOOL)tryLock; //尝试加锁(有可能已经被其他线程加锁)
- (BOOL)lockBeforeDate:(NSDate *)limit; //定时加锁
- (instancetype)initWithCondition:(NSInteger)condition //初始化
- (void)lockWhenCondition:(NSInteger)condition; //加锁
- (BOOL)tryLockWhenCondition:(NSInteger)condition; //尝试解锁
- (void)unlockWithCondition:(NSInteger)condition; //解锁
- (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit; //定时加锁
具体使用简单演示:
1、NSLock的使用:
第一步:创建锁对象
NSLock *mylock = [[NSLock alloc]init];
while(true)
{
第二步:将共享抢占资源加锁
[mylock lock];
{..........对共享抢占资源进行操作的代码..........}
第三步:操作完数据,马上释放锁,给其他的线程调用操作
[mylock unlock];
....................
}
2、NSCondition和NSRecursiveLock的使用与NSLock基本一样,只不过NSRecursiveLock会反复调用罢了,这里介绍NSCondition即可。
第一步:创建锁对象
NSCondition *mylock = [[NSCondition alloc]init];
while(true)
{
第二步:将共享抢占资源加锁
[mylock lock];
{..........对共享抢占资源进行操作的代码..........}
第三步:操作完数据,马上释放锁,给其他的线程调用操作
[mylock unlock];
....................
}
3、synchronized同步代码块的使用:
将共享抢占资源和执行代码放入其中即可
while(true)
{
@synchronized(self)
{..........对共享抢占资源进行操作的代码..........}
....................
}
说明:
4、条件锁NSConditionLock的使用:
第一步:设置条件(初始化)
NSConditionLock *conLock = [[NSConditionLock alloc] initWithCondition:No_Data];
第二步:对线程一加锁解锁(生产者)
while(true)
{
[conLock lockWhenCondition:No_Data]; //加锁
{..........对共享抢占资源进行操作的代码..........}
[conLock unlockWhenCondition:Has_Data]; //解锁,此时的条件Condition设为了内部的某一个数据,可以自定义设定
}
第三步:对线程二加锁解锁(消费者)
while(true)
{
[conLock lockWhenCondition:Has_Data]; //加锁
{..........对共享抢占资源进行操作的代码..........}
[conLock unlockWhenCondition:No_Data]; //解锁
}
5、分布锁NSDistributedLock的使用
NSDistributedLock,分布锁,文件方式实现,可以跨进程
用tryLock方法获取锁。
用unlock方法释放锁。
如果一个获取锁的进程在释放锁之前挂了,那么锁就一直得不到释放了,此时可以通过breakLock强行获取锁。
用tryLock方法获取锁。
用unlock方法释放锁。
如果一个获取锁的进程在释放锁之前挂了,那么锁就一直得不到释放了,此时可以通过breakLock强行获取锁。