美文网首页
swift 的几种锁

swift 的几种锁

作者: 流星阁 | 来源:发表于2024-06-05 15:39 被阅读0次

1、NSLock

NSLock 是最基本的锁,提供了传统的锁定和解锁机制。
场景:在多线程环境下保护一个简单的资源。

Import Foundation
class Counter {
    private var value = 0
    private let lock = NSLock()
    
    func increment() {
        lock.lock()
        value += 1
        lock.unlock()
    }
    
    func getValue() -> Int {
        lock.lock()
        let currentValue = value
        lock.unlock()
        return currentValue
    }
}

let counter = Counter()
DispatchQueue.concurrentPerform(iterations: 100) { _ in
    counter.increment()
}
print("Final counter value: \(counter.getValue())")  // 应该输出:100

2、NSRecursiveLock

NSRecursiveLock 允许同一线程多次获取同一锁,而不会导致死锁。
场景:在同一个线程中多次递归调用需要加锁的代码。

Import Foundation

class RecursiveCounter {
    private var value = 0
    private let lock = NSRecursiveLock()
    
    func increment() {
        lock.lock()
        value = recursiveIncrement(value: value)
        lock.unlock()
    }
    
    private func recursiveIncrement(value: Int) -> Int {
        lock.lock()
        defer { lock.unlock() }
        
        if value < 10 {
            return recursiveIncrement(value: value + 1)
        } else {
            return value
        }
    }
    
    func getValue() -> Int {
        lock.lock()
        let currentValue = value
        lock.unlock()
        return currentValue
    }
}

let recursiveCounter = RecursiveCounter()
recursiveCounter.increment()
print("Final counter value: \(recursiveCounter.getValue())")  // 应该输出:10

3、NSCondition / NSConditionLock

NSCondition 结合了锁和条件变量,适用于需要线程等待某个特定条件满足的情况。
场景:一组线程需要等待某个特定条件满足才能继续执行。

Import Foundation

class DataBuffer {
    private var buffer: [Int] = []
    private let condition = NSCondition()
    
    func produce(value: Int) {
        condition.lock()
        buffer.append(value)
        condition.signal() // 唤醒等待该条件的线程
        condition.unlock()
    }
    
    func consume() -> Int? {
        condition.lock()
        while buffer.isEmpty {
            condition.wait() // 等待直到有数据可消费
        }
        let value = buffer.removeFirst()
        condition.unlock()
        return value
    }
}

let buffer = DataBuffer()
DispatchQueue.global().async {
    for i in 0..<10 {
        buffer.produce(value: i)
        sleep(1)  // 模拟生产延迟
    }
}

DispatchQueue.global().async {
    for _ in 0..<10 {
        if let value = buffer.consume() {
            print("Consumed: \(value)")
        }
    }
}
import Foundation

// 定义一个用于存储数据的简单类
class SharedResource {
    var data: [String] = []
    var conditionLock = NSConditionLock(condition: 0) // 初始条件为0
}

let sharedResource = SharedResource()

// 生产者线程
let producer = Thread {
    for i in 1...5 {
        sharedResource.conditionLock.lock(whenCondition: 0)
        print("Producer: Producing item \(i)")
        sharedResource.data.append("Item \(i)")
        sharedResource.conditionLock.unlock(withCondition: 1) // 生产完成,更新条件
        sleep(1) // 模拟生产时间
    }
}

// 消费者线程
let consumer = Thread {
    for _ in 1...5 {
        sharedResource.conditionLock.lock(whenCondition: 1)
        if let item = sharedResource.data.first {
            print("Consumer: Consuming \(item)")
            sharedResource.data.removeFirst()
        }
        sharedResource.conditionLock.unlock(withCondition: 0) // 消费完成,更新条件
        sleep(2) // 模拟消费时间
    }
}

// 启动生产者和消费者线程
producer.start()
consumer.start()

// 等待线程完成
producer.join()
consumer.join()

print("All items processed.")

4、DispatchSemaphore

DispatchSemaphore 提供了一种基于计数信号量的线程同步机制。
场景:控制同一时间只能有指定数量的线程访问某个资源。

Import Dispatch
let semaphore = DispatchSemaphore(value: 3)
for i in 0..<10 {
    DispatchQueue.global().async {
        semaphore.wait() // 等待信号量
        print("Task \(i) started.")
        sleep(2) // 模拟任务执行
        print("Task \(i) finished.")
        semaphore.signal() // 释放信号量
    }
}

5、DispatchQueue (穿行队列)

使用 GCD (Grand Central Dispatch) 的串行队列,可以确保队列中的任务按顺序执行,从而实现线程安全。
场景:按顺序执行任务,保护资源访问。

Import Dispatch
let serialQueue = DispatchQueue(label: "com.example.myserialqueue")
var sharedResource = [Int]()
for i in 0..<10 {
    serialQueue.async {
        sharedResource.append(i)
        print("Appended \(i)")
    }
}

6、os_unfair_lock

os_unfair_lock 是一种低级、高性能的锁,适用于需要较高性能的锁操作环境。
场景:需要高性能且明确知道只在较短代码段中使用锁。

import os.lock

class UnfairLockCounter {
    private var value = 0
    private var lock = os_unfair_lock_s()
    
    func increment() {
        os_unfair_lock_lock(&lock)
        value += 1
        os_unfair_lock_unlock(&lock)
    }
    
    func getValue() -> Int {
        os_unfair_lock_lock(&lock)
        let currentValue = value
        os_unfair_lock_unlock(&lock)
        return currentValue
    }
}

let unfairCounter = UnfairLockCounter()
DispatchQueue.concurrentPerform(iterations: 100) { _ in
    unfairCounter.increment()
}
print("Final counter value: \(unfairCounter.getValue())")  // 应该输出:100

7、@ synchronized

Swift 本身没有直接的 @synchronized 关键字,但可以通过扩展 NSObject 来实现类似的功能。

Import Foundation
func synchronized (_ lock: AnyObject, closure: () -> Void) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}
let lockObject = NSObject()
synchronized(lockObject) {
    // 需要保护的代码区域
}

8、swift 5.5 可以使用actor来保证线程同步问题

可以参考:https://www.bennyhuo.com/2022/01/22/swift-coroutines-04-structured-concurrency/

相关文章

网友评论

      本文标题:swift 的几种锁

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