iOS 多线程-实现多读单写

西门桃桃 2022-05-18 PM 5942℃ 11条

什么是多读单写?

多个线程同时读一个变量是不需要同步的,而多个线程同时写一个变量或一个线程写而其他线程读某个变量,是需要同步的,可以总结为:“多读不互斥,而读写和多写互斥”。

实现方案:

一、加读写锁 pthread_rwlock 来实现

#import <pthread.h>

@interface FTReadWhiteSafeDic() {
    // 声明一个读写锁
   pthread_rwlock_t  lock;
  // 定义一个并发队列
    dispatch_queue_t concurrent_queue;
    // 用户数据中心, 可能多个线程需要数据访问
    NSMutableDictionary *userCenterDic;
}

@end

// 多读单写模型
@implementation FTReadWhiteSafeDic

- (id)init {
    self = [super init];
    if (self) {
      //初始化读写锁
      pthread_rwlock_init(&lock,NULL);
      // 创建数据容器
       userCenterDic = [NSMutableDictionary dictionary];
      // 通过宏定义 DISPATCH_QUEUE_CONCURRENT 创建一个并发队列
      concurrent_queue = dispatch_queue_create("read_write_queue", DISPATCH_QUEUE_CONCURRENT);
    }
    return self;
}

- (id)objectForKey:(NSString *)key {
    //加读锁
    pthread_rwlock_rdlock(&_rwlock);
    id obj = [userCenterDic objectForKey:key];
    pthread_rwlock_unlock(&_rwlock);
    return obj;
}

- (void)setObject:(id)obj forKey:(NSString *)key {
     //加写锁
    pthread_rwlock_wrlock(&_rwlock);
    [userCenterDic setObject:obj forKey:key];
    pthread_rwlock_unlock(&_rwlock);    
}

二、使用 dispatch_barrie 来实现。

@interface FTReadWhiteSafeDic() {
    // 定义一个并发队列
    dispatch_queue_t concurrent_queue;

    // 用户数据中心, 可能多个线程需要数据访问
    NSMutableDictionary *userCenterDic;
}

@end

// 多读单写模型
@implementation FTReadWhiteSafeDic

- (id)init {
    self = [super init];
    if (self) {
        // 通过宏定义 DISPATCH_QUEUE_CONCURRENT 创建一个并发队列
        concurrent_queue = dispatch_queue_create("read_write_queue", DISPATCH_QUEUE_CONCURRENT);
        // 创建数据容器
        userCenterDic = [NSMutableDictionary dictionary];
    }
    return self;
}

- (id)objectForKey:(NSString *)key {
    __block id obj;
    // 异步读取指定数据
    dispatch_async(concurrent_queue, ^{// dispatch_sync 设置为同步读取
        obj = [userCenterDic objectForKey:key];
    });
    return obj;
}

- (void)setObject:(id)obj forKey:(NSString *)key {
    // 异步栅栏调用设置数据
    dispatch_barrier_async(concurrent_queue, ^{
        [userCenterDic setObject:obj forKey:key];
    });
}

注意点:

  • 读操作 dispatch_asyncdispatch_sync 区别

dispatch_async 并发异步回调方式读取数据,当你对外部调用顺序没有要求时,可以这么调用。

dispatch_sync 并发同步读取数据,能保证外部调用顺序。此时会堵塞当前线程,当前线程需要等待读取任务执行完成,才能继续执行后边代码任务。

标签: 多线程, 线程安全

非特殊说明,本博所有文章均为博主原创。

评论啦~



已有 11 条评论


  1. Deven
    Deven

    (id)objectForKey:(NSString *)key {
    __block id obj;
    // 异步读取指定数据
    dispatch_async(concurrent_queue, ^{// dispatch_sync 设置为同步读取

    obj = [userCenterDic objectForKey:key];

    });
    return obj;
    }

    这里 async 会 返回 nil

    回复 2022-08-12 10:18
  2. vgjqelznen
    vgjqelznen

    兄弟写的非常好 https://www.cscnn.com/

    回复 2024-10-19 14:48
  3. tfuwfkevyk
    tfuwfkevyk

    博主太厉害了!

    回复 2024-11-14 02:43
  4. ywsmffzsnh
    ywsmffzsnh

    《一游记深度游上海,带你看最真实的上海》记录片高清在线免费观看:https://www.jgz518.com/xingkong/147730.html

    回复 2024-11-24 12:33
  5. idjvtsjbgy
    idjvtsjbgy

    《疯狂剧团》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/37078.html

    回复 2024-11-26 10:42
  6. cjpmwgryje
    cjpmwgryje

    《馒头日记》国产动漫高清在线免费观看:https://www.jgz518.com/xingkong/48766.html

    回复 2024-11-26 15:54
  7. iupengaqyu
    iupengaqyu

    《医妃难囚第二季》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/21651.html

    回复 2024-11-30 08:08
  8. yeyiazrwut
    yeyiazrwut

    《疯狂剧团》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/37078.html

    回复 2024-12-04 07:40
  9. ngbgefektf
    ngbgefektf

    《巴顿将军》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/67762.html

    回复 2024-12-04 19:50
  10. emzlkxafhj
    emzlkxafhj

    《兴风作浪3》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/64505.html

    回复 2024-12-15 17:40
  11. vmlqohljvy
    vmlqohljvy

    《归来战神是奶爸》短片剧高清在线免费观看:https://www.jgz518.com/xingkong/25883.html

    回复 2025-01-04 00:00