美文网首页iOSiOS Developer
多线程锁的使用

多线程锁的使用

作者: 踏云小子 | 来源:发表于2017-05-31 18:57 被阅读29次

    方法一:用NSLock

    TestObj *obj = [[TestObj alloc] init];
    //线程1
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [lock lock];
            [obj method1];
            sleep(30);
            [lock unlock];
        });
        
        //线程2
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);//以保证让线程2的代码后执行
            [lock lock];
            [obj method2];
            [lock unlock];
        });
    

    方法二:用@synchronized

    TestObj *obj = [[TestObj alloc] init];
        //线程1
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            @synchronized (obj) {
                [obj method1];
            }
            sleep(30);
        });
        
        //线程2
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);//以保证让线程2的代码后执行
            @synchronized (obj) {
                [obj method2];
            }
        });
    

    方法三:用GCD的dispatch_semaphore_t和dispatch_semaphore_wait

    • dispatch_semaphore_create(num),这里的num相当于古代将军发的令牌数目,如果num是1,表示可以分配给一个将领去执行任务,实例代码代码如下:
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"method1");
            sleep(10);
            dispatch_semaphore_signal(semaphore);
        });
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(1);
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"method2");
            dispatch_semaphore_signal(semaphore);
        });
    

    这里dispatch_semaphore_create(1)创建的是一个令牌,所以会先执行method1任务,然后等待10秒后发送一个信号(dispatch_semaphore_signal(semaphore))使信号量+1,再执行method2任务

    • num如果是0,没有令牌,就立即执行dispatch_semaphore_wait方法:
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"method1");
            sleep(10);
            dispatch_semaphore_signal(semaphore);
        });
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(1);
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"method2");
            dispatch_semaphore_signal(semaphore);
        });
    

    这里只执行到dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);,永远不会执行NSLog(@"method1")和下面的method2方法

    • num如果是2,分配2个令牌,使得下面两个进程都可以执行:
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"method1");
            sleep(10);
            dispatch_semaphore_signal(semaphore);
        });
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(1);
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"method2");
            dispatch_semaphore_signal(semaphore);
        });
    

    方法三:用pthread_mutex互斥锁

    • 初始化
      导入#import <pthread.h>
    @interface XYThread ()
    {
        pthread_mutex_t mutex;  //声明pthread_mutex_t的结构
    }
    @end
    
    //在viewDidLoad里初始化
    - (void)viewDidLoad {
        [super viewDidLoad];
        pthread_mutex_init(&mutex, NULL);
    }
    
    • 加锁and解锁
    //加锁
    pthread_mutex_lock(&mutex);
    
    /*你的代码*/
    
    //解锁
    pthread_mutex_unlock(&mutex);
    
    • 释放锁
    - (void)dealloc{
        pthread_mutex_destroy(&mutex);  //释放该锁的数据结构
    }
    

    针对函数递归调用的情况,可以使用递归锁

    - (void)viewDidLoad {
        NSMutableArray *array = @[].mutableCopy;
        
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);//定义锁的类别
        __block pthread_mutex_t mutex;
        pthread_mutex_init(&mutex, &attr);
            pthread_mutexattr_destroy (&attr);
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            pthread_mutex_lock(&mutex);
            [array addObject:@"1"];
            [NSThread sleepForTimeInterval:1];
            NSLog(@"thread1");
            pthread_mutex_unlock(&mutex);
        });
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            pthread_mutex_lock(&mutex);
            [array addObject:@"2"];
            [NSThread sleepForTimeInterval:2];
            NSLog(@"thread2");
            pthread_mutex_unlock(&mutex);
        });
    }
    

    相关文章

      网友评论

        本文标题:多线程锁的使用

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