NSConditionLock解決回調(diào)順序場景

NSConditionLock條件鎖在開發(fā)中幾乎很少用到,雖然知道他的作用但是之前并沒有碰到一個用它解決問題的場景。
描述如下一個場景:三個異步任務(wù)在并發(fā)隊列中,同時執(zhí)行一個耗時任務(wù)X,當(dāng)X執(zhí)行完畢之后會回調(diào)一次數(shù)據(jù),如何保證調(diào)用順序和回調(diào)順序一致?
eg:ABC三個異步任務(wù)依次書寫,并發(fā)異步下假如實際調(diào)用順序為BCA,希望回調(diào)順序也是BCA,但其實可能A執(zhí)行X時最先處理完,但不回調(diào),等待BC回調(diào)過后再進(jìn)行回調(diào),即調(diào)用順序為BCA,回調(diào)順序為BCA,且并發(fā)。

利用NSConditionLock可以比較方便實現(xiàn)這個效果,思路如下:通過一個容器記錄方法的調(diào)用順序,主動解鎖第一個調(diào)用,第一個調(diào)用一次解鎖剩下的調(diào)用。

前置一個問題,如果我先進(jìn)行條件解鎖,再進(jìn)行同條件加鎖,此處無效,像下面這樣

self.conditionLock.unlock(withCondition: 4)
self.conditionLock.lock(whenCondition: 4)
print("aaa")

正文:
變量部分:

var methodIndex : Array<Int> = Array()  //標(biāo)記調(diào)用順序的容器
    var methodIndexLock : NSLock = NSLock.init() //給容器讀寫加鎖的互斥鎖
    var methodCurrnetLock : Int = 0 //當(dāng)前解鎖到的位置
    
    lazy var conditionLock : NSConditionLock = {
        return NSConditionLock.init(condition: 0)
    }() //條件鎖
//并發(fā)調(diào)用三個異步任務(wù),為了比較直觀,我把第一個任務(wù)進(jìn)行延遲
    func testConditionLock() {
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.5, execute: {
            print("第一個任務(wù)開始了")
            self.someMethod(1) {
                print("第一個任務(wù)返回了")
            }
        })
        DispatchQueue.global().async {
            print("第二個任務(wù)開始了")
            self.someMethod(2) {
                print("第二個任務(wù)返回了")
            }
        }
        DispatchQueue.global().async {
            print("第三個任務(wù)開始了")
            self.someMethod(3) {
                print("第三個任務(wù)返回了")
            }
        }
        
        //這里備注下:此處是希望解鎖第一個加鎖的,也就是像上面前置問題那樣,使第一把條件鎖無效
        DispatchQueue.main.asyncAfter(deadline: .now()+1) {
            self.conditionLock.unlock(withCondition: self.methodIndex[0])
        }
    }
//第一個參數(shù)只是一個標(biāo)識,不代表調(diào)用順序
func someMethod(_ actionIndex:Int,callback:()->Void) {
        //對容器讀寫加鎖
        self.methodIndexLock.lock()
        self.methodIndex.append(actionIndex)
        self.methodIndexLock.unlock()
        
        let t = Double(arc4random() % 10)
        Thread.sleep(forTimeInterval: t) //此處進(jìn)行休眠,模擬耗時操作
        print(actionIndex,t)
        self.conditionLock.lock(whenCondition: actionIndex)
        callback()
        self.methodCurrnetLock += 1
        guard self.methodIndex.count > self.methodCurrnetLock else {
            return
        }
        self.conditionLock.unlock(withCondition: self.methodIndex[self.methodCurrnetLock])
        print(self.methodCurrnetLock,self.methodIndex)
        
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容