雖然作者在開發(fā)中經(jīng)常會(huì)用到多線程阀参,但是對(duì)于死鎖肝集、線程阻塞等問題還是比較模糊,一般都是先寫吧蛛壳,有問題再改杏瞻,現(xiàn)在閑下來了,是時(shí)候總結(jié)一波了衙荐,本文主要總結(jié)一下同步/異步捞挥、串行/并行、死鎖忧吟、線程阻塞等問題
- 串行/并行
串行(Serial Queue):同一時(shí)間內(nèi)砌函,隊(duì)列中只能執(zhí)行一個(gè)任務(wù),只有當(dāng)前的任務(wù)執(zhí)行完成之后溜族,才能執(zhí)行下一個(gè)任務(wù)
并行(concurrent Queue):同時(shí)允許多個(gè)任務(wù)執(zhí)行(并行隊(duì)列中才會(huì)有多個(gè)線程讹俊,串行的只有一個(gè)線程) - 同步/異步
同步(Sync):等到當(dāng)前的任務(wù)執(zhí)行完成,線程才會(huì)繼續(xù)去執(zhí)行下面的任務(wù)
異步(Async):線程會(huì)立即返回煌抒,無需等待就會(huì)繼續(xù)直線下面的任務(wù) - 死鎖
兩個(gè)或以上的線程互相等待彼此執(zhí)行仍劈,通常情況有(在同一
個(gè)串行
隊(duì)列中執(zhí)行同步
操作,或兩個(gè)線程互相依賴等情況) - 阻塞
只要是同步
操作都會(huì)阻塞一個(gè)線程
所以
1.在遇到需要多線程相互依賴的情況摧玫,一定要注意,不要兩個(gè)線程互相依賴绑青,這樣會(huì)造成死鎖
2.在使用同步線程時(shí)诬像,要注意不要在同一個(gè)串行隊(duì)列中使用,還要注意線程阻塞問題
下面是相關(guān)代碼
申請(qǐng)一個(gè)串行隊(duì)列
// 串行
let serQueue = DispatchQueue(label: "serial")
申請(qǐng)一個(gè)并行隊(duì)列
// 并行
let conQueue = DispatchQueue(label: "concurrent", attributes: .concurrent)
串行同步闸婴、串行異步
// 串行同步
serQueue.sync {
print("串行同步")
}
// 串行異步
serQueue.async {
print("串行異步")
}
并行同步坏挠、并行異步
// 并行同步
conQueue.sync {
print("并行同步")
}
// 并行異步
conQueue.async {
print("并行異步")
}
死鎖情況
線程相互依賴
let opA = Operation()
let opB = Operation()
opA.addDependency(opB)
opB.addDependency(opA)
串行中同步
// 死鎖
serQueue.async {
serQueue.sync {
print(1)
}
}
serQueue.sync {
serQueue.sync {
print(1)
}
}