I was wondering if Swift 4 variables are atomic or not. So I did the following test.
Below is my test code.
class Test {
var count = 0
let lock = NSLock()
func testA() {
count = 0
let queueA = DispatchQueue(label: "Q1")
let queueB = DispatchQueue(label: "Q2")
let queueC = DispatchQueue(label: "Q3")
queueA.async {
for _ in 1...1000 {
self.increase()
}
}
queueB.async {
for _ in 1...1000 {
self.increase()
}
}
queueC.async {
for _ in 1...1000 {
self.increase()
}
}
}
func increase() {
self.count += 1
print(count)
}
}
The conclusion is as follows: lock.lock()and lock.unlock() comment .
3
3
3
4
5
...
2999
3000
The conclusion is as follows: lock.lock()and lock.unlock without commenting .
1
2
3
4
5
...
2999
3000
My problem:
If the variable is countnon-atomic, queueA, queueB, and queueC must invoke asynchronously increase(), resulting in random access and printing count.
So, in my opinion, there is a moment, for example, queueA and queueB got countequal to 15, and both of them increase countby 1 ( count += 1), so the counter should be equal to 16, although two increments are performed.
, , .
, , count ?
:
, , , .
1. increase() , .
func increase() {
lock.lock()
self.count += 1
array.append(self.count)
lock.unlock()
}
2. :
@IBAction func tapped(_ sender: Any) {
let testObjc = Test()
testObj.testA()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+3) {
print(self.testObj.array)
}
}
NSLock:
NSLock:
[1,2,3,...,2999,3000]