美文网首页
锁的使用

锁的使用

作者: YN吾爱 | 来源:发表于2022-03-23 15:07 被阅读0次

一、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 <objc/objc-sync.h>

        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 <objc/objc-sync.h>

#import <pthread.h>

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 <libkern/OSAtomic.h>

    __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 解锁成功");

    });

相关文章

  • 谈谈Python线程中的“锁机制”

    何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议...

  • 递增场景

    synchronized使用系统重量级的锁 AtomicXXX使用无锁-自旋锁,CAS-类似于乐观锁, 所以效率优...

  • 锁的使用

  • 锁的使用

    一、NSLock 加锁lock 解锁unlock NSLock *lock = [[NSLock alloc]in...

  • iOS-锁-@synchronized

    @synchronized,同步锁,又名对象锁,由于其使用简单,基本上是在iOS开发中使用最频繁的锁。 使用方式如...

  • Lock 的使用

    Lock 的使用 使用 ReentrantLock 类 lock():获取锁 unlock():释放锁 效果和 s...

  • 多线程 -线程安全

    线程安全隐患 资源共享 解决数据错乱问题使用互斥锁互斥锁使用格式: @synchronized(锁对象) { //...

  • 【PHP】针对业务场景的需要,合理的使用 MySQL 乐观锁与悲

    针对 MySQL的乐观锁与悲观锁的使用,基本都是按照业务场景针对性使用的。针对每个业务场景,对应的使用锁。但是两种...

  • MySQL的锁机制和加锁原理

    首先对mysql锁进行划分: 按照锁的粒度划分:行锁、表锁、页锁 按照锁的使用方式划分:共享锁、排它锁(悲观锁的一...

  • Day20 作业

    使用锁

网友评论

      本文标题:锁的使用

      本文链接:https://www.haomeiwen.com/subject/qnvcjrtx.html