iOS 的串行隊列和并發(fā)隊列中的任務(wù)是如何執(zhí)行的

我們都知道隊列有串行隊列和并發(fā)隊列畦徘,主隊列就屬于串行隊列,串行隊列里面的任務(wù)是按順序執(zhí)行旬陡,并發(fā)隊列里的任務(wù)是并發(fā)執(zhí)行拓颓,至于并發(fā)幾個線程去執(zhí)行,這就交給GCD 了描孟。
但是有個問題需要思考一下驶睦,我們都知道任務(wù)要執(zhí)行,先要從隊列中取出匿醒,然后再分配到線程中執(zhí)行场航,也就是分三步:1.從隊列中取出任務(wù),2.執(zhí)行任務(wù)廉羔,3.任務(wù)執(zhí)行完畢溉痢。所謂串行隊列里面的任務(wù)按順序執(zhí)行,這個按順序是指的按順序取出憋他,還是等前一個任務(wù)執(zhí)行完畢再執(zhí)行下一個任務(wù)呢孩饼?寫個代碼測試一下。

串行隊列同步異步執(zhí)行測試

1.串行隊列中同步執(zhí)行一個任務(wù)竹挡,異步執(zhí)行一個任務(wù)

let seralQueue = DispatchQueue(label: "dispatchSeralQueue")
//任務(wù)一
seralQueue.sync {
            for i in 0...10 {
                debugPrint("queueTest seralQueue1: \(Thread.current), \(i)")
            }
        }
//任務(wù)二
        seralQueue.async {
            for i in 0...10 {
                debugPrint("queueTest seralQueue2: \(Thread.current), \(i)")
            }
        }
"queueTest seralQueue1: <_NSMainThread: 0x600002360540>{number = 1, name = main}, 0"
"queueTest seralQueue1: <_NSMainThread: 0x600002360540>{number = 1, name = main}, 1"
"queueTest seralQueue1: <_NSMainThread: 0x600002360540>{number = 1, name = main}, 2"
"queueTest seralQueue1: <_NSMainThread: 0x600002360540>{number = 1, name = main}, 3"
"queueTest seralQueue1: <_NSMainThread: 0x600002360540>{number = 1, name = main}, 4"
"queueTest seralQueue1: <_NSMainThread: 0x600002360540>{number = 1, name = main}, 5"
"queueTest seralQueue2: <NSThread: 0x60000235eec0>{number = 4, name = (null)}, 0"
"queueTest seralQueue2: <NSThread: 0x60000235eec0>{number = 4, name = (null)}, 1"
"queueTest seralQueue2: <NSThread: 0x60000235eec0>{number = 4, name = (null)}, 2"
"queueTest seralQueue2: <NSThread: 0x60000235eec0>{number = 4, name = (null)}, 3"
"queueTest seralQueue2: <NSThread: 0x60000235eec0>{number = 4, name = (null)}, 4"
"queueTest seralQueue2: <NSThread: 0x60000235eec0>{number = 4, name = (null)}, 5"

可以看到镀娶,第一個任務(wù)是在主線程執(zhí)行,第二個任務(wù)在子線程執(zhí)行揪罕,這符合代碼邏輯梯码,從輸出順序上來看,在串行隊列中好啰,雖然任務(wù)二用了異步執(zhí)行的方式轩娶,也開了新的線程,但是順序卻是任務(wù)一執(zhí)行完畢之后框往,任務(wù)二才會執(zhí)行罢坝。

2.串行隊列中異步執(zhí)行兩個任務(wù)

let seralQueue = DispatchQueue(label: "dispatchSeralQueue")
// 任務(wù)一
seralQueue.async {
            for i in 0...5 {
                debugPrint("queueTest seralQueue1: \(Thread.current), \(i)")
            }
        }
//任務(wù) 二
        seralQueue.async {
            for i in 0...5 {
                debugPrint("queueTest seralQueue2: \(Thread.current), \(i)")
            }
        }
"queueTest seralQueue1: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 0"
"queueTest seralQueue1: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 1"
"queueTest seralQueue1: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 2"
"queueTest seralQueue1: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 3"
"queueTest seralQueue1: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 4"
"queueTest seralQueue1: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 5"
"queueTest seralQueue2: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 0"
"queueTest seralQueue2: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 1"
"queueTest seralQueue2: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 2"
"queueTest seralQueue2: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 3"
"queueTest seralQueue2: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 4"
"queueTest seralQueue2: <NSThread: 0x600001cbd700>{number = 6, name = (null)}, 5"

可以看到,兩個任務(wù)都在子線程執(zhí)行搅窿,而且是按順序的嘁酿,第一個任務(wù)執(zhí)行完畢,才會輪到第二個任務(wù)執(zhí)行男应。

3.串行隊列同步執(zhí)行兩個任務(wù)

let seralQueue = DispatchQueue(label: "dispatchSeralQueue")
seralQueue.sync {
            for i in 0...5 {
                debugPrint("queueTest seralQueue1: \(Thread.current), \(i)")
            }
        }
        seralQueue.sync {
            for i in 0...5 {
                debugPrint("queueTest seralQueue2: \(Thread.current), \(i)")
            }
        }
"queueTest seralQueue1: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 0"
"queueTest seralQueue1: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 1"
"queueTest seralQueue1: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 2"
"queueTest seralQueue1: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 3"
"queueTest seralQueue1: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 4"
"queueTest seralQueue1: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 5"
"queueTest seralQueue2: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 0"
"queueTest seralQueue2: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 1"
"queueTest seralQueue2: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 2"
"queueTest seralQueue2: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 3"
"queueTest seralQueue2: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 4"
"queueTest seralQueue2: <_NSMainThread: 0x600002fb0080>{number = 1, name = main}, 5"

同步執(zhí)行順序隊列任務(wù)闹司,沒有開啟新線程,任務(wù)按順序執(zhí)行沐飘。

并發(fā)隊列同步異步執(zhí)行測試

并發(fā)隊列異步執(zhí)行兩個任務(wù)

let conCurrentQueue = DispatchQueue(label: "dispatchConcurrentQueue", attributes: .concurrent)
conCurrentQueue.async {
            for i in 0...5 {
                debugPrint("queueTest conCurrentQueue1: \(Thread.current), \(i)")
            }
        }
        conCurrentQueue.async {
            for i in 0...5 {
                debugPrint("queueTest conCurrentQueue2: \(Thread.current), \(i)")
            }
        }
"queueTest conCurrentQueue2: <NSThread: 0x60000018e780>{number = 5, name = (null)}, 0"
"queueTest conCurrentQueue1: <NSThread: 0x600000189e80>{number = 6, name = (null)}, 0"
"queueTest conCurrentQueue2: <NSThread: 0x60000018e780>{number = 5, name = (null)}, 1"
"queueTest conCurrentQueue1: <NSThread: 0x600000189e80>{number = 6, name = (null)}, 1"
"queueTest conCurrentQueue2: <NSThread: 0x60000018e780>{number = 5, name = (null)}, 2"
"queueTest conCurrentQueue1: <NSThread: 0x600000189e80>{number = 6, name = (null)}, 2"
"queueTest conCurrentQueue2: <NSThread: 0x60000018e780>{number = 5, name = (null)}, 3"
"queueTest conCurrentQueue1: <NSThread: 0x600000189e80>{number = 6, name = (null)}, 3"
"queueTest conCurrentQueue2: <NSThread: 0x60000018e780>{number = 5, name = (null)}, 4"
"queueTest conCurrentQueue1: <NSThread: 0x600000189e80>{number = 6, name = (null)}, 4"
"queueTest conCurrentQueue2: <NSThread: 0x60000018e780>{number = 5, name = (null)}, 5"
"queueTest conCurrentQueue1: <NSThread: 0x600000189e80>{number = 6, name = (null)}, 5"

可以看到兩個任務(wù)之間是交叉執(zhí)行的游桩,并沒有順序關(guān)系,而且也開辟了新的線程耐朴。

并發(fā)隊列同步執(zhí)行兩個任務(wù)

conCurrentQueue.sync {
            for i in 0...5 {
                debugPrint("queueTest conCurrentQueue1: \(Thread.current), \(i)")
            }
        }
        conCurrentQueue.sync {
            for i in 0...5 {
                debugPrint("queueTest conCurrentQueue2: \(Thread.current), \(i)")
            }
        }
"queueTest conCurrentQueue1: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 0"
"queueTest conCurrentQueue1: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 1"
"queueTest conCurrentQueue1: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 2"
"queueTest conCurrentQueue1: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 3"
"queueTest conCurrentQueue1: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 4"
"queueTest conCurrentQueue1: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 5"
"queueTest conCurrentQueue2: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 0"
"queueTest conCurrentQueue2: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 1"
"queueTest conCurrentQueue2: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 2"
"queueTest conCurrentQueue2: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 3"
"queueTest conCurrentQueue2: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 4"
"queueTest conCurrentQueue2: <_NSMainThread: 0x60000142c040>{number = 1, name = main}, 5"

可以看到并發(fā)隊列同步執(zhí)行借卧,并沒有開啟新的線程,任務(wù)也是按順序執(zhí)行完畢的

并發(fā)隊列中筛峭,同步執(zhí)行一個任務(wù)铐刘,異步執(zhí)行一個任務(wù)

let conCurrentQueue = DispatchQueue(label: "dispatchConcurrentQueue", attributes: .concurrent)
conCurrentQueue.sync {
            for i in 0...5 {
                debugPrint("queueTest conCurrentQueue1: \(Thread.current), \(i)")
            }
        }
        conCurrentQueue.async {
            for i in 0...5 {
                debugPrint("queueTest conCurrentQueue2: \(Thread.current), \(i)")
            }
        }
"queueTest conCurrentQueue1: <_NSMainThread: 0x600000d6c000>{number = 1, name = main}, 0"
"queueTest conCurrentQueue1: <_NSMainThread: 0x600000d6c000>{number = 1, name = main}, 1"
"queueTest conCurrentQueue1: <_NSMainThread: 0x600000d6c000>{number = 1, name = main}, 2"
"queueTest conCurrentQueue1: <_NSMainThread: 0x600000d6c000>{number = 1, name = main}, 3"
"queueTest conCurrentQueue1: <_NSMainThread: 0x600000d6c000>{number = 1, name = main}, 4"
"queueTest conCurrentQueue1: <_NSMainThread: 0x600000d6c000>{number = 1, name = main}, 5"
"queueTest conCurrentQueue2: <NSThread: 0x600000d24d40>{number = 7, name = (null)}, 0"
"queueTest conCurrentQueue2: <NSThread: 0x600000d24d40>{number = 7, name = (null)}, 1"
"queueTest conCurrentQueue2: <NSThread: 0x600000d24d40>{number = 7, name = (null)}, 2"
"queueTest conCurrentQueue2: <NSThread: 0x600000d24d40>{number = 7, name = (null)}, 3"
"queueTest conCurrentQueue2: <NSThread: 0x600000d24d40>{number = 7, name = (null)}, 4"
"queueTest conCurrentQueue2: <NSThread: 0x600000d24d40>{number = 7, name = (null)}, 5"

異步執(zhí)行的任務(wù)開啟了新的線程,但是兩個任務(wù)之間還是順序的關(guān)系影晓,一個任務(wù)執(zhí)行完畢镰吵,才會開始執(zhí)行下一個任務(wù)。

結(jié)論

串行隊列+同步執(zhí)行=不開新線程挂签,任務(wù)依次執(zhí)行
串行隊列+異步執(zhí)行=開啟新線程疤祭,任務(wù)依次執(zhí)行
并發(fā)隊列+同步執(zhí)行=不開新線程,任務(wù)依次執(zhí)行
并發(fā)隊列+異步執(zhí)行=開啟新線程饵婆,任務(wù)并發(fā)執(zhí)行

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勺馆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侨核,更是在濱河造成了極大的恐慌草穆,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芹关,死亡現(xiàn)場離奇詭異续挟,居然都是意外死亡,警方通過查閱死者的電腦和手機侥衬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門诗祸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人轴总,你說我怎么就攤上這事直颅。” “怎么了怀樟?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵功偿,是天一觀的道長。 經(jīng)常有香客問我往堡,道長械荷,這世上最難降的妖魔是什么共耍? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮吨瞎,結(jié)果婚禮上痹兜,老公的妹妹穿的比我還像新娘。我一直安慰自己颤诀,他們只是感情好字旭,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著崖叫,像睡著了一般遗淳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上心傀,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天屈暗,我揣著相機與錄音,去河邊找鬼剧包。 笑死恐锦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疆液。 我是一名探鬼主播一铅,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼堕油!你這毒婦竟也來了潘飘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤掉缺,失蹤者是張志新(化名)和其女友劉穎卜录,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眶明,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡艰毒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了搜囱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丑瞧。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蜀肘,靈堂內(nèi)的尸體忽然破棺而出绊汹,到底是詐尸還是另有隱情,我是刑警寧澤扮宠,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布西乖,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏获雕。R本人自食惡果不足惜薄腻,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望典鸡。 院中可真熱鬧被廓,春花似錦、人聲如沸萝玷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽球碉。三九已至,卻和暖如春仓蛆,著一層夾襖步出監(jiān)牢的瞬間睁冬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工看疙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留豆拨,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓能庆,卻偏偏與公主長得像施禾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搁胆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容