假设封装一个缓存工具类,通过字典存放数据,假设在多线程中存储数据,那么就有必要加锁,保证数据的安全

1.DispatchSemaphore信号量

public struct Cache{

    private static var data = [String: Any]()
    public static func get(_ key: String) -> Any? {
        data[key]
    }
    
    // value=2 代表"同时"可以有2条线程可以访问
    private static var lock = DispatchSemaphore.init(value: 1)
    
    public static func set(_ key: String, value: Any) {
        // 加锁
        lock.wait()
        
        // 更严谨的做法使用defer代码块
        defer { // 不管有没异常,最后都解锁
            lock.signal()
        }
        data[key] = value
        
        // 一旦执行的代码抛出异常,那么将永远无法解锁
       // lock.signal()
    }
}

2.NSLock示例

public struct Cache{
    
    private static var data = [String: Any]()
    public static func get(_ key: String) -> Any? {
        data[key]
    }
    
    private static var lock = NSLock()
    
    public static func set(_ key: String, value: Any) {
        // 加锁
        lock.lock()
        
        defer { // 不管有没异常,最后都解锁
            lock.unlock()
        }
        data[key] = value
    }
}

3.NSRecursiveLock递归锁,使用方法同NSLock一样,

public struct Cache{
    
    private static var data = [String: Any]()
    public static func get(_ key: String) -> Any? {
        data[key]
    }
    
    // 递归锁
    private static var lock = NSRecursiveLock()
    
    
    public static func set(_ key: String, value: Any) {
        // 加锁
        lock.lock()
        
        defer { // 不管有没异常,最后都解锁
            lock.unlock()
        }
        
        // 假设这里使用递归方法,又调用了set方法,必须要使用递归锁
        data[key] = value
    }
}