美文网首页
当单例遇见多线程

当单例遇见多线程

作者: 大写的空气 | 来源:发表于2021-07-06 18:04 被阅读0次

    遥想当年,单例类中定义了一个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的简单封装。此时的打印结果如下


    加锁后

    是的,它还是那么浪荡不羁爱自由,东打一炮西打一枪。
    细细去品味,它却规矩了很多,已能区分孩子的父母到底是谁!
    所以、关键时候还是要戴套保护自己...😁

    相关文章

      网友评论

          本文标题:当单例遇见多线程

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