基本知識(shí)
在多核的CPU中,一個(gè)CPU(核心),一個(gè)核心基本可以運(yùn)行多個(gè)線程湿右,每個(gè)執(zhí)行一段時(shí)間切換到下一個(gè)線程,但是如果線程過(guò)多就會(huì)產(chǎn)生 切換上下文的時(shí)間消耗罚勾,所以線程不能過(guò)多毅人。由于現(xiàn)在CPU執(zhí)行速度過(guò)快,內(nèi)存極大的拖慢了速度漾唉,所以在CPU中會(huì)有L1、L2堰塌、L3的緩存赵刑,速度極快,用于充當(dāng)CPU和內(nèi)存的橋梁提高速度
CPU多級(jí)緩存
由于每個(gè)CPU都有自己的緩存區(qū)场刑,為了保證多個(gè)CPU緩存區(qū)域使用到共享數(shù)據(jù)如何保證數(shù)據(jù)的一致性般此,就出現(xiàn)了MESI
的協(xié)議
M(修改):當(dāng)前CPU緩存獨(dú)占且已修改了共享數(shù)據(jù),即與主存的數(shù)據(jù)不一致,需要被寫(xiě)回主內(nèi)存牵现,當(dāng)寫(xiě)回主存以后變?yōu)镋狀態(tài)
E(獨(dú)享):一個(gè)CPU緩存獨(dú)占數(shù)據(jù)且和主存中的一致铐懊,當(dāng)被讀取時(shí)進(jìn)入S狀態(tài),當(dāng)被修改時(shí)進(jìn)入M狀態(tài)
S(共享): 該緩存與主存中的數(shù)據(jù)一致瞎疼,可能被多個(gè)CPU緩存科乎,當(dāng)其中cpu對(duì)數(shù)據(jù)做出修改時(shí),其他cpu緩存的該數(shù)據(jù)可以進(jìn)入I(無(wú)效)狀態(tài)
I(無(wú)效):緩存無(wú)效贼急,其他cpu修改了共享數(shù)據(jù)
除了I狀態(tài)茅茂,其他狀態(tài)都可以被讀取,寫(xiě)請(qǐng)求只能在M狀態(tài)或者是E狀態(tài)下可以被寫(xiě)入太抓,如果處于S必須將其他cpu中的數(shù)據(jù)變?yōu)镮狀態(tài)才可寫(xiě)入
CPU優(yōu)化
CPU可能會(huì)為了提高運(yùn)算速度而調(diào)整代碼原有順序空闲,但是會(huì)保證結(jié)果一致,但是多核環(huán)境下不一定走敌,因?yàn)槎嗪诉\(yùn)行可能第一個(gè)依賴第二個(gè)核的線程的結(jié)果在做操作碴倾,但是結(jié)果CPU優(yōu)化把第一個(gè)CPU的代碼先運(yùn)行就會(huì)造成某些意料之外的結(jié)果
使用多處理器
如果使用一個(gè)雙處理器中運(yùn)行一個(gè)單線程程序,等于放棄了其中一半的資源,其實(shí)單個(gè)處理器也能運(yùn)行多線程程序,如果一個(gè)線程是單線程的,在這個(gè)處理器等待同步IO時(shí),處理器依舊是空閑狀態(tài),如果使用程序多線程,當(dāng)程序遇到阻塞時(shí),另外一個(gè)線程也能執(zhí)行
使用多線程的好處
多線程毋庸置疑的,在把多個(gè)任務(wù)分給多個(gè)線程,能提高其效率,但是如果創(chuàng)建過(guò)多的線程可能反而會(huì)降低效率, 因?yàn)檫^(guò)多的線程會(huì)引起上下文切換,因?yàn)樘幚砥髟趫?zhí)行的時(shí)候是分時(shí)執(zhí)行,需要在不同的線程中來(lái)回切換,這就導(dǎo)致了大量時(shí)間消耗
線程安全舉例
在我們常用的servlet中,在客戶端發(fā)送請(qǐng)求過(guò)來(lái)時(shí),都是多線程訪問(wèn)servlet,但是我們好像重來(lái)沒(méi)有關(guān)注過(guò)它,那么它們是線程安全的嗎,如下,她是線程安全的,因?yàn)樗且粋€(gè)無(wú)狀態(tài)類,每一個(gè)線程進(jìn)入以后,都會(huì)新建那些變量,對(duì)象之間沒(méi)有共享狀態(tài),故而是安全的
下面這個(gè)servlet是線程不安全的,因?yàn)樗鼈冊(cè)L問(wèn)了類變量,類變量是對(duì)象之間共享的,也就是線程之間共享的,多個(gè)線程操作同一個(gè)共享變量就會(huì)造成線程安全問(wèn)題,因?yàn)?code>i++并不是一個(gè)原子性操作,它的操作可以被分解為三個(gè)步驟,取出i,i+1,賦值給i,多個(gè)線程運(yùn)行時(shí),可能阻塞在其中一步,就運(yùn)行其他線程,導(dǎo)致的結(jié)果就是多個(gè)線程修改后的變量結(jié)果一致
競(jìng)爭(zhēng)條件和數(shù)據(jù)競(jìng)爭(zhēng)
競(jìng)爭(zhēng)條件
:指的是當(dāng)一個(gè)線程在執(zhí)行一個(gè)判斷語(yǔ)句為真,然后阻塞去執(zhí)行線程2,線程2把判斷語(yǔ)句里的指值更新到了false,這是線程1就會(huì)出現(xiàn)預(yù)料之外的問(wèn)題,例如懶漢式單例就存在競(jìng)爭(zhēng)條件
數(shù)據(jù)競(jìng)爭(zhēng)
:上面那個(gè)線程非安全的舉例就是數(shù)據(jù)競(jìng)爭(zhēng),由于沒(méi)有對(duì)共享變量做同步處理,多個(gè)線程訪問(wèn)時(shí),可能在去讀到還未修改時(shí),另外一個(gè)線程也在讀取修改
原子性
有線程A和B,當(dāng)線程B在執(zhí)行多個(gè)操作時(shí),必須保證這個(gè)B的操作要么同時(shí)操作,要么不操作