更新時(shí)間:2020-06-30 14:53:24 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2187次
1)Java中能創(chuàng)建volatile數(shù)組嗎?
能,Java中可以創(chuàng)建volatile類型數(shù)組,不過只是一個(gè)指向數(shù)組的引用,而不是整個(gè)數(shù)組。我的意思是,如果改變引用指向的數(shù)組,將會(huì)受到volatile的保護(hù),但是如果多個(gè)線程同時(shí)改變數(shù)組的元素,volatile標(biāo)示符就不能起到之前的保護(hù)作用了。
2)volatile能使得一個(gè)非原子操作變成原子操作嗎?
一個(gè)典型的例子是在類中有一個(gè)long類型的成員變量。如果你知道該成員變量會(huì)被多個(gè)線程訪問,如計(jì)數(shù)器、價(jià)格等,你最好是將其設(shè)置為volatile。為什么?因?yàn)镴ava中讀取long類型變量不是原子的,需要分成兩步,如果一個(gè)線程正在修改該long變量的值,另一個(gè)線程可能只能看到該值的一半(前32位)。但是對(duì)一個(gè)volatile型的long或double變量的讀寫是原子。
3)volatile修飾符的有過什么實(shí)踐?
一種實(shí)踐是用volatile修飾long和double變量,使其能按原子類型來讀寫。double和long都是64位寬,因此對(duì)這兩種類型的讀是分為兩部分的,第一次讀取第一個(gè)32位,然后再讀剩下的32位,這個(gè)過程不是原子的,但Java中volatile型的long或double變量的讀寫是原子的。volatile修復(fù)符的另一個(gè)作用是提供內(nèi)存屏障(memory barrier),例如在分布式框架中的應(yīng)用。簡(jiǎn)單的說,就是當(dāng)你寫一個(gè)volatile變量之前,Java內(nèi)存模型會(huì)插入一個(gè)寫屏障(write barrier),讀一個(gè)volatile變量之前,會(huì)插入一個(gè)讀屏障(read barrier)。意思就是說,在你寫一個(gè)volatile域時(shí),能保證任何線程都能看到你寫的值,同時(shí),在寫之前,也能保證任何數(shù)值的更新對(duì)所有線程是可見的,因?yàn)閮?nèi)存屏障會(huì)將其他所有寫的值更新到緩存。
4)volatile類型變量提供什么保證?
volatile變量提供順序和可見性保證,例如,JVM或者JIT為了獲得更好的性能會(huì)對(duì)語句重排序,但是volatile類型變量即使在沒有同步塊的情況下賦值也不會(huì)與其他語句重排序。volatile提供happens-before的保證,確保一個(gè)線程的修改能對(duì)其他線程是可見的。某些情況下,volatile還能提供原子性,如讀64位數(shù)據(jù)類型,像long和double都不是原子的,但volatile類型的double和long就是原子的。
5)10個(gè)線程和2個(gè)線程的同步代碼,哪個(gè)更容易寫?
從寫代碼的角度來說,兩者的復(fù)雜度是相同的,因?yàn)橥酱a與線程數(shù)量是相互獨(dú)立的。但是同步策略的選擇依賴于線程的數(shù)量,因?yàn)樵蕉嗟木€程意味著更大的競(jìng)爭(zhēng),所以你需要利用同步技術(shù),如鎖分離,這要求更復(fù)雜的代碼和專業(yè)知識(shí)。
6)你是如何調(diào)用wait()方法的?使用if塊還是循環(huán)?為什么?
wait()方法應(yīng)該在循環(huán)調(diào)用,因?yàn)楫?dāng)線程獲取到CPU開始執(zhí)行的時(shí)候,其他條件可能還沒有滿足,所以在處理前,循環(huán)檢測(cè)條件是否滿足會(huì)更好。下面是一段標(biāo)準(zhǔn)的使用wait和notify方法的代碼:
//?The?standard?idiom?for?using?the?wait?method
synchronized(obj)?{
while(condition?does?not?hold)
obj.wait();?//?(Releases?lock,?and?reacquires?on?wakeup)
...?//?Perform?action?appropriate?to?condition
}
7)什么是多線程環(huán)境下的偽共享(false sharing)?
偽共享是多線程系統(tǒng)(每個(gè)處理器有自己的局部緩存)中一個(gè)眾所周知的性能問題。偽共享發(fā)生在不同處理器的上的線程對(duì)變量的修改依賴于相同的緩存行,如下圖所示:
有經(jīng)驗(yàn)程序員的Java面試題
偽共享問題很難被發(fā)現(xiàn),因?yàn)榫€程可能訪問完全不同的全局變量,內(nèi)存中卻碰巧在很相近的位置上。如其他諸多的并發(fā)問題,避免偽共享的最基本方式是仔細(xì)審查代碼,根據(jù)緩存行來調(diào)整你的數(shù)據(jù)結(jié)構(gòu)。
以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“2020年程序員常見Java面試題含答案”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743