遥想当年,单例类中定义了一个Array属性,用于缓存某些数据,以达到直接从内存中读取来提升读取速度。这个过程中一直有一个顽固的bug伴随终生,怎么查找都不得其法
下面场景模仿单例类中Array的读写操作,复现当年遇见的它
var marray = [Int]()
for i in 0 ... 10 {
DispatchQueue.global().async {
print("打印内容:\(i)")
marray.append(i)
}
DispatchQueue.global().async {
print("打印内容数组\(marray.count)最后一个:\(marray.last)")
}
}
当然,正常使用场景时候,读写几乎不会在一起,这也就造成排查问题的无从下手
打印结果如下:
多线程读写打印结果
分析上面存在的问题:
打印内容已经输出4,当令一个线程去读取时,显示的数组长度为1(正常应该为4),打印出的数组最后一个值为0(正常应该也为4)。结果显然不符合预期。之余它,会出来一系列的问题。
它、为什么变了,我该怎么办?
锁、锁死它。留不住你的心,我还留不住你人不成
修改后代码
var marray = [Int]()
for i in 0 ... 10 {
DispatchQueue.global().async {
LSLock.unfairLock {
print("打印内容:\(i)")
marray.append(i)
}
}
DispatchQueue.global().async {
LSLock.unfairLock {
print("打印内容数组\(marray.count)最后一个:\(marray.last)")
}
}
}
里面的LSLock类是对unfair_lock的简单封装。此时的打印结果如下
加锁后
是的,它还是那么浪荡不羁爱自由,东打一炮西打一枪。
细细去品味,它却规矩了很多,已能区分孩子的父母到底是谁!
所以、关键时候还是要戴套保护自己...😁
网友评论