美文网首页
线程安全存取器GCDSafeAccessor

线程安全存取器GCDSafeAccessor

作者: Jason1226 | 来源:发表于2021-07-13 16:26 被阅读0次

数据的读写一般容易引发几个问题:

  1. 在主线程中大量数据读写容易阻塞主线程,造成UI卡住。
  2. 读操作和写操作同时执行,或多个写操作同时执行,容易引发并发问题。
    读写锁的说明参考:https://www.jianshu.com/p/a3a9b9460ab8

因此设计一个高效的线程安全存取器很有必要。

class GCDSafeAccessor: NSObject {

    let qos: DispatchQoS
    lazy var queue = DispatchQueue(label: "gcd_safe_accessor", qos: qos, attributes: .concurrent)
 
    init(qos: DispatchQoS = .default) {
        self.qos = qos
        super.init()
    }
    
    // 小数据写入可以在主线程同步执行
    func safeReadSync<T>(_ callback: @escaping () -> T?) -> T? {
        var data: T?
        queue.sync {
            data = callback()
        }
        return data
    }
    // 大数据写入需要在子线程异步进行,避免主线程卡住
    func safeReadAsync(_ callback: @escaping () -> Void) {
        queue.async(execute: callback)
    }
    
    func safeWriteAsync(_ callback: @escaping () -> Void) {
        queue.async(flags: .barrier, execute: callback)
    }
}

使用方式:

    var dict: [String: String] = ["key": "value"]

        // 当前线程同步读取数据方式1
        _ = accessor.safeReadSync {
            let value = self.dict["key"]
        }

        // 当前线程同步读取数据方式2
        let value: String? = accessor.safeReadSync {
            let value = self.dict["key"]
            return value
        }

        // 子线程异步读取数据
        accessor.safeReadAsync {
            let value = self.dict["key"]
        }
        
        // 子线程异步写数据
        accessor.safeWriteAsync {
            self.dict["key"] = "value"
        }

GCDSafeAccessor 提供同步和异步两种方式读取数据,可针对大数据或者同时大量读操作选择异步方式。同步读取数据也提供两种回调方式,方式1 读取数据在闭包内返回,方式 2读取的数据作为接口返回值返回,可根据代码结构选择不同方式。
线程安全方面,如果对读和写同时加上相同锁,则效率不高,因为多个读操作不需要加锁。因此,异步读操作使用并发队列让多个读操作可以并发执行;写操作则使用barrier来实现与读操作的互斥,并且能让多个写操作同步进行。

相关文章

  • 关于JAVA中各种Map的场景选择

    HashMap :非线程安全 存取速度快。 ConcurrentHashMap:并发场景使用 ,线程安全 Tree...

  • 问题:使用atomic一定是线程安全的吗?

    atomic不是绝对的线程安全。atomic的本意是指属性的存取方法是线程安全的,并不保证整个对象是线程安全的。 ...

  • iOS编程中atomic和nonatomic的区别

    atomic atomic 的本意是指属性的存取方法是线程安全(thread safe).但不保证整个对象都是线程...

  • FMDB源码解析

    FMDatabase这个类不是线程安全的,如果多个线程同时使用一个FMDatabase对象来存取数据,可能会发生数...

  • HashMap学习笔记1

    先说说HashMap的几个特点: 1、无序的(那它的存取速度咋还那么快呢?) 2、线程不安全的(存取不同步) 第二...

  • atomic是绝对安全的么?

    atomic只能保证属性的存取是线程安全的,并不能保证整个对象是线程安全的。首先看一下代码以及打印结果: 错误的分...

  • 线程(一)

    如何保证线程安全? 考察点:线程参考回答: 通过合理的时间调度,避开共享资源的存取冲突。另外,在并行任务设计上可以...

  • 编写高质量iOS与OS X代码的52个有效方法--第41条

    第41条:多用派发队列,少用同步锁 1.错误的线程安全的存取方法 -(NSString*)someString{ ...

  • 存储器的存储方式

    存储器中数据常用的存取方式有顺序存取、直接存取、随机存取和相联存取等四种。(1)顺序存取:存储器的数据以记录的形式...

  • PHP7的windows安装

    1.[下载window下的PHP解释器][1] 选择线程安全的64位版本[线程安全与线程不安全的区别][2]下载完...

网友评论

      本文标题:线程安全存取器GCDSafeAccessor

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