美文网首页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);
    });
}

相关文章

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • 多线程(四)

    上篇多线程(三)我们看了多线程的安全隐患 以及各种锁的简单使用,接下来我们来看看锁的比较、以及自旋锁、互斥锁比较 ...

  • iOS开发底层相关基础知识点

    正确使用多线程同步锁@synchronized() YYKit学习笔记

  • Python多任务_线程

    简单使用 多线程共享全局变量-互斥锁

  • synchronized 到底该不该用?

    在多线程环境中,锁的使用是避免不了的,使用锁时候有多种锁供我们选择,比如 ReentrantLock、CountD...

  • 多线程环境中,让Java开发者又爱又恨的synchronized

    前言 在多线程环境中,锁的使用是避免不了的,使用锁时候有多种锁供我们选择,比如 ReentrantLock、Cou...

  • C链表

    互斥锁:链表用在多线程中保证顺序,多个线程会操作同一个链表,互斥锁保证多线程操作的安全,互斥锁分情况使用,链表并不...

  • go sync包的读写锁RWMutex的使用

    sync包的读写锁RWMutex的使用(sync.RWMutex) 我们使用“读写”锁的场景主要是在多线程的安全操...

  • 【python】多线程(高级篇)

    多线程互斥锁 关于如何使用Lock( 锁 ) 【目标】学习如何加锁,获取钥匙,释放锁. 语句如下: 【注释】loc...

  • 线程同步与互斥

    Linux--线程编程 多线程编程-互斥锁 线程同步与互斥 互斥锁 信号量 条件变量 互斥锁 互斥锁的基本使用...

网友评论

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

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