多线程同步加锁主要方式有3种:NSLock(普通锁)、NSCondition(状态锁)、synchronized同步代码块

还有少用的NSRecursiveLock(递归锁)、NSConditionLock(条件锁)、NSDistributedLock(分布锁)。

 

区别:

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>其他方法:

       - (void)wait;                                          //睡眠等待解锁

     - (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强行获取锁。