/**

/**

#import <Foundation/Foundation.h>
#import "pthread.h"

int main(int args , const char * argv[]) {

 @autoreleasepool {
        
        dispatch_queue_t queue = dispatch_queue_create("com.gcd.lock.queue", DISPATCH_QUEUE_CONCURRENT);
        
        
        // 注 : NSLock锁
        __block NSInteger nslock_number = 0;
        NSLock *lock = [[NSLock alloc] init];
        dispatch_apply(10, queue, ^(size_t idx) {
            [lock lock];
            if (idx%2 == 0) {
                nslock_number ++;
            }else {
                nslock_number --;
            }
            NSLog(@"NSLock number %ld",nslock_number);
            [lock unlock];
        });
        NSLog(@"NSLock number finally : %ld \n",nslock_number);
        
        
        // 注 : synchronized
        // 1. 只允许修饰Objective-C对象
        __block NSNumber *sychronized_number = @(0);
        dispatch_apply(10, queue, ^(size_t idx) {
            @synchronized (sychronized_number) {
                if (idx%2 == 0) {
                    sychronized_number = @(sychronized_number.integerValue + 1);
                }else {
                    sychronized_number = @(sychronized_number.integerValue - 1);
                }
            }
            NSLog(@"sychronized number %@",sychronized_number);
        });
        NSLog(@"sychronized number finally %@ \n",sychronized_number);
        
        
        // 注 : NSCondition、NSConditionLock
        /*
         * 1. 加锁和解锁需要在同一线程
         * 2. 可以设置加/解锁条件
         * 3. 注意初始化时候设置响应条件,否自条件加锁将永远获取不到锁
         * 4. NSCondition需要外部条件变量来设置条件锁,NSConditionLock则自带一个条件变量
         */
        __block NSInteger condition_number = 0;
        NSConditionLock *conditionLock = [[NSConditionLock alloc] initWithCondition:1];
        dispatch_apply(10, queue, ^(size_t idx) {
            [conditionLock lockWhenCondition:1];
            if (idx%2 == 0) {
                condition_number ++;
            }else {
                condition_number --;
            }
            NSLog(@"NSConditionLock number %ld",condition_number);
            [conditionLock unlockWithCondition:1];
        });
        NSLog(@"NSConditionLock number finally : %ld \n",condition_number);
        
        
        /*
         * 注 : NSRecursiveLock
         * 1. 递归锁可以被同一线程多次请求,而不会死锁。
         */
        __block NSInteger recursive_number = 1;
        NSRecursiveLock *recursive_lock = [[NSRecursiveLock alloc] init];
        
        void(^RecursiveMethod)(NSInteger);
        __weak __block void(^WeakRecursiveMethod)(NSInteger);
        WeakRecursiveMethod = RecursiveMethod = ^(NSInteger value) {
            [recursive_lock lock];
            if (value%2 == 0) {
                recursive_number --;
            }else {
                recursive_number ++;
            } 
            if (recursive_number > 2) {
                recursive_number--;
                NSLog(@"recursive_number value => %ld", recursive_number);
                sleep(1);
                WeakRecursiveMethod(recursive_number);
            }
            NSLog(@"recursive_number ==> %ld", recursive_number);
            [recursive_lock unlock];
        };
        
        dispatch_apply(10, queue, ^(size_t idx) {
            RecursiveMethod(idx);
        });
        NSLog(@"recursive_number finally ==> %ld", recursive_number);
        
        
        /*
         * pthread_mutex : C语言下多线程加锁方式
         * 1. Implicit declaration of function 'pthread_mutex_unlock' is invalid in C99 : 导入 pthread.h即可
         )
         */
        __block NSInteger pthread_number = 0;
        __block pthread_mutex_t pthread_lock;
        pthread_mutex_init(&pthread_lock,NULL);
        dispatch_apply(10, queue, ^(size_t idx) {
            pthread_mutex_lock(&pthread_lock);
            if (idx %2 == 0) {
                pthread_number --;
            } else {
                pthread_number ++;
            }
            NSLog(@"pthread_number ==> %ld", pthread_number);
            pthread_mutex_unlock(&pthread_lock);
        });
        NSLog(@"pthread_number finally ==> %ld", pthread_number);
        
        /*
         * OSSpinLink : 自旋锁
         */
        __block NSInteger osspin_number = 0;
        __block OSSpinLock osspin_lock = OS_SPINLOCK_INIT;
        dispatch_apply(1000, queue, ^(size_t idx) {
            OSSpinLockLock(&osspin_lock);
            if (idx %2 == 0) {
                osspin_number --;
            } else {
                osspin_number ++;
            }
            NSLog(@"osspin_number ==> %ld", osspin_number);
            OSSpinLockUnlock(&osspin_lock);
        });
        NSLog(@"osspin_number finally ==> %ld", osspin_number);
        
    }
    
}

递归锁

NSRecursiveLock 是递归锁,他和 NSLock 的区别在于,NSRecursiveLock 可以在一个线程中重复加锁(反正单线程内任务是按顺序执行的,不会出现资源竞争问题),NSRecursiveLock 会记录上锁和解锁的次数,当二者平衡的时候,才会释放锁,其它线程才可以上锁成功。

NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
    static void (^RecursiveBlock)(int);
    RecursiveBlock = ^(int value) {
        [lock lock];
        if (value > 0) {
            NSLog(@"value:%d", value);
            RecursiveBlock(value - 1);
        }
        [lock unlock];
    };
    RecursiveBlock(2);
});

2016-08-19 14:43:12.327 ThreadLockControlDemo[1878:145003] value:2
2016-08-19 14:43:12.327 ThreadLockControlDemo[1878:145003] value:1

为了解决这个问题是为了解决什么问题?

如上面的示例,如果用 NSLock 的话,lock 先锁上了,但未执行解锁的时候,就会进入递归的下一层,而再次请求上锁,阻塞了该线程,线程被阻塞了,自然后面的解锁代码不会执行,而形成了死锁。而 NSRecursiveLock 递归锁就是为了解决这个问题