swift - DispatchQueue 是否也锁定了里面使用的资源?
问题描述
class Factory {
var localSharedResource
var localQueue = DispatchQueue(label: "localQueue")
let threadLock = NSLock()
func modify(){
localQueue.async {
self.threadLock.lock()
localSharedResource = "a change is made here"
self.threadLock.unlock()
}
}
}
如果 localSharedResource 也被其他线程访问,我应该使用 lock 吗?
解决方案
这取决于。
如果所有访问localSharedResource
都通过localQueue.sync
or包装localQueue.async
,则threadLock
可以删除该属性。串行队列 ( localQueue
) 已经在进行所有必要的同步。上式可以改写为:
class Factory {
var localSharedResource
var localQueue = DispatchQueue(label: "localQueue")
func modify(){
localQueue.async {
localSharedResource = "a change is made here"
}
}
}
然而,如果有多个线程可能访问localSharedResource
并且localQueue
是其中之一,那么localSharedResource
需要有额外的同步方式。通过NSLock
或使用专用串行队列。
例如
class Factory {
var localSharedResource
var localQueue = DispatchQueue(label: "localQueue")
let threadLock = NSLock()
func modify(){
localQueue.async {
self.threadLock.lock()
localSharedResource = "a change is made here"
self.threadLock.unlock()
}
}
func modifyAgain() {
DispatchQueue.global().async {
self.threadLock.lock()
localSharedResource = "another change"
self.threadLock.unlock()
}
}
}
推荐阅读
- excel - 从一个工作簿粘贴到另一个工作簿时如何设置我的复制范围?
- ruby-on-rails - 在与三个模型的 has_many_through 关联中优化查询
- python - 比较字符串元素并检查最后一个字符是否不同
- php - 如何在 IntelliJ 中为 Web 应用程序执行 php 脚本?
- navigation - Vaadin Flow:使用 SplitLayout 和 @ParentLayout 时导航损坏(?)
- java - 从 AspectJ 访问私有静态成员(例如记录器)
- c - 尝试将 node.js unix 套接字客户端连接到 C 程序时出现 EPROTOTYPE 错误
- c# - 如何修复 ReportViewer 在 ASP.NET MVC 中向多个用户显示相同的报告?
- android - react-native-firebase crashlytics 未显示在 firebase 仪表板上
- sql - MS-SQL:一般更改数据库的 FileGrowth 参数