锁的使用

一、NSLock

加锁lock

解锁unlock

NSLock *lock = [[NSLock alloc]init];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [lock lock];

        NSLog(@"线程一");

        sleep(10);

        [lock unlock];

    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        if ([lock tryLock]) {

            NSLog(@"线程二");

            sleep(1);

            [lock unlock];

        }else{

            NSLog(@"测试加锁失败");

        }

    });

二、NSConditionLock条件锁

跟NSLock类似,多了个条件锁Condition

//主线程中

        NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:0];


        //线程1

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            [lock lockWhenCondition:1];

            NSLog(@"线程1");

            sleep(2);

            [lock unlock];

        });


        //线程2

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            sleep(5);//以保证让线程2的代码后执行

            if ([lock tryLockWhenCondition:0]) {

                NSLog(@"线程2");

                [lock unlockWithCondition:2];

                NSLog(@"线程2解锁成功");

            } else {

                NSLog(@"线程2尝试加锁失败");

            }

        });


        //线程3

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            sleep(2);//以保证让线程2的代码后执行

            if ([lock tryLockWhenCondition:2]) {

                NSLog(@"线程3");

                [lock unlock];

                NSLog(@"线程3解锁成功");

            } else {

                NSLog(@"线程3尝试加锁失败");

            }

        });


        //线程4

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            sleep(3);//以保证让线程2的代码后执行

            if ([lock tryLockWhenCondition:2]) {

                NSLog(@"线程4");

                [lock unlockWithCondition:1];

                NSLog(@"线程4解锁成功");

            } else {

                NSLog(@"线程4尝试加锁失败");

            }

        });

三、递归锁NSRecursiveLock

实际是一个同步锁

#import

        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);

                    sleep(3);

                    RecursiveBlock(value - 1);

                }

                [lock unlock];

            };

            dispatch_async(dispatch_get_main_queue(), ^{

                NSLog(@"开始睡觉");

                sleep(2);

                NSLog(@"睡了2秒");

                sleep(4);

                NSLog(@"睡了4秒");

            });


            NSLog(@"递归一开始");

            RecursiveBlock(5);

            NSLog(@"递归一完成");

            sleep(1);

            RecursiveBlock(3);

        });

四、线程、锁判断NSCondition

__block NSMutableArray *products = [NSMutableArray array];

    NSCondition *condition = [NSCondition new];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"线程一开始");

        [condition lock];

        while (products.count<1) {

            NSLog(@"线程一等待");

            //线程等待

            [condition wait];

        }

        NSLog(@"线程一执行");

        [products removeObjectAtIndex:0];

        [condition unlock];

    });


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        sleep(1);

        NSLog(@"线程二");

        [condition lock];

        [products addObject:@1];

        //唤醒等待的线程

        [condition signal];

        [condition unlock];

    });

五、## @synchronized

@synchronized (self) {

//some code

    }

    //等价于

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLock *lock = [NSLock new];

        [lock lock];

//some code

        [lock unlock];

    });

//等价于

    NSString *test = @"test";

    id synchronizeTarget = (id)test;

    @try {

        objc_sync_enter(synchronizeTarget);

        test = nil;

    } @finally {

        objc_sync_exit(synchronizeTarget);

    }

六、信号量dispatch_semaphore_t

dispatch_semaphore_t signal = dispatch_semaphore_create(0);

dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 9 * NSEC_PER_SEC);

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        sleep(3);

        NSLog(@"signal");

        dispatch_semaphore_signal(signal);

    });

    NSLog(@"wait");

    dispatch_semaphore_wait(signal, overTime);

    NSLog(@"end");

七、互坼锁mutex

#import

#import

static pthread_mutex_t theLock;

- (void)example5 {

/*

PTHREAD_MUTEX_NORMAL 缺省类型,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后先进先出原则获得锁。

PTHREAD_MUTEX_ERRORCHECK 检错锁,如果同一个线程请求同一个锁,则返回 EDEADLK,否则与普通锁类型动作相同。这样就保证当不允许多次加锁时不会出现嵌套情况下的死锁。

PTHREAD_MUTEX_RECURSIVE 递归锁,允许同一个线程对同一个锁成功获得多次,并通过多次 unlock 解锁。

PTHREAD_MUTEX_DEFAULT 适应锁,动作最简单的锁类型,仅等待解锁后重新竞争,没有等待队列。

*/

    pthread_mutex_init(&theLock, NULL);


//设置类型

    pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr);

    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

    pthread_mutex_init(&theLock, &attr);

    pthread_mutexattr_destroy(&attr);

    pthread_t thread;

    pthread_create(&thread, NULL, threadMethord1, NULL);


    pthread_t thread2;

    pthread_create(&thread2, NULL, threadMethord2, NULL);

}

void *threadMethord1() {

    pthread_mutex_lock(&theLock);

    printf("线程1\n");

    sleep(2);

    pthread_mutex_unlock(&theLock);

    printf("线程1解锁成功\n");

    return 0;

}

void *threadMethord2() {

    sleep(1);

    pthread_mutex_lock(&theLock);

    printf("线程2\n");

    pthread_mutex_unlock(&theLock);

    printf("线程2解锁成功\n");

    return 0;

}

八、自旋锁OSSpinLock (因为线程安全问题,iOS 10.0以后废弃了,取而代之的是互斥锁os_unfair_lock_lock,类似于pthread_mutex)

#import

    __block OSSpinLock oslock = OS_SPINLOCK_INIT;

    //线程1

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"线程1 准备上锁");

        OSSpinLockLock(&oslock);

        sleep(4);

        NSLog(@"线程1");

        OSSpinLockUnlock(&oslock);

        NSLog(@"线程1 解锁成功");

        NSLog(@"--------------------------------------------------------");

    });

    //线程2

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"线程2 准备上锁");

        OSSpinLockLock(&oslock);

        NSLog(@"线程2");

        OSSpinLockUnlock(&oslock);

        NSLog(@"线程2 解锁成功");

    });

你可能感兴趣的:(锁的使用)