You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中synchronized机制实现无效问题求助

Swift多线程同步的几种实现方式(对应Java synchronized)

嘿,作为Swift新手刚接触多线程确实得转换下思路,毕竟Swift的并发模型和Java不太一样~ 我先帮你把没写完的代码补全,再给你几种对应Java synchronized的同步实现方案,都是Swift里常用的方式:

先补全你的基础代码框架

假设你要实现的是多个线程操作同一个共享资源(比如一个计数器),先把你的代码补完整:

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

// 被多个线程访问的共享类
class TheDemo {
    var counter = 0
}

// 自定义线程类
public class TestThread {
    var name: String
    var theDemo: TheDemo
    
    init(_ name: String, _ theDemo: TheDemo) {
        self.name = name
        self.theDemo = theDemo
    }
    
    // 启动线程执行任务
    func start() {
        Thread { [weak self] in
            guard let self = self else { return }
            // 这里是需要同步的操作
            for _ in 0..<1000 {
                self.theDemo.counter += 1
            }
            print("\(self.name) 执行完成,当前counter值:\(self.theDemo.counter)")
        }.start()
    }
}

// 测试代码
let demo = TheDemo()
let thread1 = TestThread("线程1", demo)
let thread2 = TestThread("线程2", demo)
thread1.start()
thread2.start()

不过上面的代码没有同步处理,会出现线程安全问题,counter的最终值大概率不是预期的2000,接下来给你几种可靠的同步方案:


方案1:使用NSLock(手动加锁,最接近Java synchronized)

类似Java的synchronized代码块,我们可以用NSLock给共享资源的操作加锁,保证同一时间只有一个线程能执行临界区代码:

import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true

class TheDemo {
    var counter = 0
    private let lock = NSLock() // 定义一个专属锁
    
    // 同步方法,类似Java的synchronized方法
    func increment() {
        lock.lock()
        defer { lock.unlock() } // defer保证锁一定会被释放,避免死锁
        counter += 1
    }
}

public class TestThread {
    var name: String
    var theDemo: TheDemo
    
    init(_ name: String, _ theDemo: TheDemo) {
        self.name = name
        self.theDemo = theDemo
    }
    
    func start() {
        Thread { [weak self] in
            guard let self = self else { return }
            for _ in 0..<1000 {
                self.theDemo.increment() // 调用同步方法
            }
            print("\(self.name) 执行完成,当前counter值:\(self.theDemo.counter)")
        }.start()
    }
}

let demo = TheDemo()
let thread1 = TestThread("线程1", demo)
let thread2 = TestThread("线程2", demo)
thread1.start()
thread2.start()

这里lock.lock()和lock.unlock()就对应Java的synchronized代码块,defer语句能保证即使方法抛出异常,锁也会被释放,从根源避免死锁风险。


方案2:使用GCD串行队列(隐式同步,更贴合Swift风格)

Swift里更常用的是用GCD的串行队列实现同步:把所有需要访问共享资源的任务放到同一个串行队列里,队列会自动保证任务按顺序执行,完全不需要手动管理锁:

import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true

class TheDemo {
    var counter = 0
    private let syncQueue = DispatchQueue(label: "com.example.syncQueue") // 创建串行队列
    
    func increment() {
        // 把任务放到串行队列异步执行
        syncQueue.async { [weak self] in
            guard let self = self else { return }
            self.counter += 1
        }
        // 如果需要等待任务完成后再继续,可以用sync替代async
        // syncQueue.sync { ... }
    }
    
    // 获取当前counter值也要同步,避免读取到中间的不一致值
    func getCounter() -> Int {
        var result = 0
        syncQueue.sync {
            result = self.counter
        }
        return result
    }
}

public class TestThread {
    var name: String
    var theDemo: TheDemo
    
    init(_ name: String, _ theDemo: TheDemo) {
        self.name = name
        self.theDemo = theDemo
    }
    
    func start() {
        Thread { [weak self] in
            guard let self = self else { return }
            for _ in 0..<1000 {
                self.theDemo.increment()
            }
            print("\(self.name) 执行完成,当前counter值:\(self.theDemo.getCounter())")
        }.start()
    }
}

let demo = TheDemo()
let thread1 = TestThread("线程1", demo)
let thread2 = TestThread("线程2", demo)
thread1.start()
thread2.start()

这种方式代码更简洁,也减少了手动锁可能带来的失误,是Swift开发者常用的同步方案。


方案3:使用Swift Actor(现代Swift并发模型,官方推荐)

从Swift 5.5开始,苹果推出了Actor模型,这是官方推荐的线程安全方案。Actor内部的所有方法默认都是线程安全的,自动避免数据竞争,完全不需要手动加锁:

import PlaygroundSupport
import Foundation
PlaygroundPage.current.needsIndefiniteExecution = true

// 定义Actor,自动保证内部状态的线程安全
actor TheDemo {
    var counter = 0
    
    func increment() {
        counter += 1
    }
    
    func getCounter() -> Int {
        return counter
    }
}

public class TestThread {
    var name: String
    var theDemo: TheDemo
    
    init(_ name: String, _ theDemo: TheDemo) {
        self.name = name
        self.theDemo = theDemo
    }
    
    func start() {
        // Actor的方法需要在异步上下文中调用,用Task创建异步任务
        Task { [weak self] in
            guard let self = self else { return }
            for _ in 0..<1000 {
                await self.theDemo.increment()
            }
            let finalCount = await self.theDemo.getCounter()
            print("\(self.name) 执行完成,当前counter值:\(finalCount)")
        }
    }
}

let demo = TheDemo()
let thread1 = TestThread("线程1", demo)
let thread2 = TestThread("线程2", demo)
thread1.start()
thread2.start()

Actor是Swift并发模型的核心,它通过await关键字处理异步调用,自动保证同一时间只有一个线程访问Actor的内部状态,是未来Swift并发的主流方式,新项目优先推荐使用。


总结一下:如果习惯Java的手动锁逻辑,用NSLock;如果想更贴合Swift的写法,用GCD串行队列;如果是Swift 5.5+的新项目,优先用Actor,它更安全也更简洁。

内容的提问来源于stack exchange,提问作者besabestin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:22:53