初探多線程(C#)
1. 理解多線程 在軟件編寫(xiě)中,多線程是一個(gè)非常重要的概念。由于傳統(tǒng)教育的原因,很多人對(duì)多線程一無(wú)所知。然而,在接觸電腦十年后,我意識(shí)到自己對(duì)多線程一無(wú)所知。為了填補(bǔ)這個(gè)知識(shí)空白,我決定仔細(xì)研究多線
1. 理解多線程
在軟件編寫(xiě)中,多線程是一個(gè)非常重要的概念。由于傳統(tǒng)教育的原因,很多人對(duì)多線程一無(wú)所知。然而,在接觸電腦十年后,我意識(shí)到自己對(duì)多線程一無(wú)所知。為了填補(bǔ)這個(gè)知識(shí)空白,我決定仔細(xì)研究多線程,并將我的學(xué)習(xí)心得寫(xiě)下來(lái),供和我一樣的人參考,共同進(jìn)步。
2. 理解線程異步
在單CPU環(huán)境下,每個(gè)時(shí)間片內(nèi)只能執(zhí)行一個(gè)線程,即只能做一件事情。當(dāng)一個(gè)線程的時(shí)間片用完時(shí),系統(tǒng)會(huì)掛起該線程,開(kāi)始執(zhí)行另一個(gè)線程。通過(guò)這種輪流執(zhí)行的方式,CPU在多個(gè)線程之間交替執(zhí)行運(yùn)算,從而產(chǎn)生了多個(gè)任務(wù)“同時(shí)”執(zhí)行的效果。線程異步可以解決耗時(shí)任務(wù)導(dǎo)致界面控件無(wú)法使用的問(wèn)題。通過(guò)創(chuàng)建一個(gè)次線程來(lái)執(zhí)行耗時(shí)任務(wù),主線程則負(fù)責(zé)處理界面控件響應(yīng)事件,通過(guò)線程調(diào)度器在不同線程之間進(jìn)行快速切換,模擬出多個(gè)任務(wù)“同時(shí)”被執(zhí)行的效果。
3. 線程異步的案例
為了更好地理解線程異步的概念,我們可以通過(guò)一個(gè)實(shí)例來(lái)演示。在主線程中,我們創(chuàng)建了一個(gè)次線程來(lái)執(zhí)行一個(gè)耗時(shí)的任務(wù)。運(yùn)行結(jié)果顯示,數(shù)字是交替出現(xiàn)的,這說(shuō)明了線程之間的時(shí)間片切換。
4. 補(bǔ)充概念(前臺(tái)線程與后臺(tái)線程)
前臺(tái)線程能夠阻止應(yīng)用程序的終止,只有所有前臺(tái)線程終止后,應(yīng)用程序才會(huì)關(guān)閉。而后臺(tái)線程則不同,當(dāng)所有前臺(tái)線程終止時(shí),后臺(tái)線程會(huì)被自動(dòng)終止,無(wú)論后臺(tái)線程是否正在執(zhí)行任務(wù)。默認(rèn)情況下,通過(guò)()方法創(chuàng)建的線程都是前臺(tái)線程,可以通過(guò)將線程的屬性IsBackground設(shè)為true來(lái)將線程轉(zhuǎn)換為后臺(tái)線程。
5. 多線程難點(diǎn)(并發(fā)問(wèn)題演示)
盡管看起來(lái)多線程很簡(jiǎn)單,只需要多次調(diào)用new Thread()即可,但是在多個(gè)線程訪問(wèn)同一個(gè)資源時(shí)會(huì)出現(xiàn)問(wèn)題。例如,在網(wǎng)絡(luò)訂票系統(tǒng)中,如果一個(gè)客戶買(mǎi)了一張票,另一個(gè)客戶再來(lái)購(gòu)買(mǎi)時(shí),按理說(shuō)是不能再買(mǎi)的。然而,由于線程是獨(dú)立運(yùn)行的,互相之間沒(méi)有干擾,所以怎樣才能讓另一個(gè)線程知道資源已經(jīng)被修改了呢?這就涉及到線程同步的問(wèn)題,同時(shí)也引入了諸如死鎖和并發(fā)等概念。
6. 線程同步
線程同步也稱為阻塞調(diào)用,即在任務(wù)執(zhí)行完之前不返回,線程被掛起。在C#中,可以使用lock關(guān)鍵字來(lái)實(shí)現(xiàn)線程同步。在lock關(guān)鍵字的作用范圍內(nèi)的代碼將是線程安全的。lock關(guān)鍵字需要定義一個(gè)標(biāo)記,只有獲得該標(biāo)記的線程才能進(jìn)入鎖定范圍。當(dāng)鎖定的是一個(gè)實(shí)例級(jí)對(duì)象的私有方法時(shí),可以使用方法本身所在對(duì)象的引用作為鎖定標(biāo)記。