更新時間:2020-02-10 10:25:31 來源:動力節(jié)點 瀏覽3281次

1.什么是活鎖、饑餓、無鎖、死鎖?
死鎖、活鎖、饑餓是關(guān)于多線程是否活躍出現(xiàn)的運行阻塞障礙問題,如果線程出現(xiàn)了這三種情況,即線程不再活躍,不能再正常地執(zhí)行下去了。
死鎖
死鎖是多線程中最差的一種情況,多個線程相互占用對方的資源的鎖,而又相互等對方釋放鎖,此時若無外力干預(yù),這些線程則一直處理阻塞的假死狀態(tài),形成死鎖。
舉個例子,A同學(xué)搶了B同學(xué)的鋼筆,B同學(xué)搶了A同學(xué)的書,兩個人都相互占用對方的東西,都在讓對方先還給自己自己再還,這樣一直爭執(zhí)下去等待對方還而又得不到解決,
老師知道此事后就讓他們相互還給對方,這樣在外力的干預(yù)下他們才解決,當(dāng)然這只是個例子沒有老師他們也能很好解決,計算機不像人如果發(fā)現(xiàn)這種情況沒有外力干預(yù)還是會一直阻塞下去的。
活鎖
活鎖這個概念大家應(yīng)該很少有人聽說或理解它的概念,而在多線程中這確實存在。
活鎖恰恰與死鎖相反,死鎖是大家都拿不到資源都占用著對方的資源,而活鎖是拿到資源卻又相互釋放不執(zhí)行。
當(dāng)多線程中出現(xiàn)了相互謙讓,都主動將資源釋放給別的線程使用,這樣這個資源在多個線程之間跳動而又得不到執(zhí)行,這就是活鎖。
饑餓
我們知道多線程執(zhí)行中有線程優(yōu)先級這個東西,優(yōu)先級高的線程能夠插隊并優(yōu)先執(zhí)行,這樣如果優(yōu)先級高的線程一直搶占優(yōu)先級低線程的資源,導(dǎo)致低優(yōu)先級線程無法得到執(zhí)行,這就是饑餓。
當(dāng)然還有一種饑餓的情況,一個線程一直占著一個資源不放而導(dǎo)致其他線程得不到執(zhí)行,與死鎖不同的是饑餓在以后一段時間內(nèi)還是能夠得到執(zhí)行的,如那個占用資源的線程結(jié)束了并釋放了資源。
無鎖
無鎖,即沒有對資源進行鎖定,即所有的線程都能訪問并修改同一個資源,但同時只有一個線程能修改成功。
無鎖典型的特點就是一個修改操作在一個循環(huán)內(nèi)進行,線程會不斷的嘗試修改共享資源,如果沒有沖突就修改成功并退出否則就會繼續(xù)下一次循環(huán)嘗試。
所以,如果有多個線程修改同一個值必定會有一個線程能修改成功,而其他修改失敗的線程會不斷重試直到修改成功。之前的文章我介紹過JDK的CAS原理及應(yīng)用即是無鎖的實現(xiàn)。
可以看出,無鎖是一種非常良好的設(shè)計,它不會出現(xiàn)線程出現(xiàn)的跳躍性問題,鎖使用不當(dāng)肯定會出現(xiàn)系統(tǒng)性能問題,雖然無鎖無法全面代替有鎖,但無鎖在某些場合下是非常高效的。
2.線程和進程的區(qū)別是什么?
進程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產(chǎn)生影響,而線程只是一個進程中的不同執(zhí)行路徑。
線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。
但對于一些要求同時進行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進程。
3.Java實現(xiàn)線程有哪幾種方式?
(1)繼承Thread類實現(xiàn)多線程
?。?)實現(xiàn)Runnable接口方式實現(xiàn)多線程
?。?)使用ExecutorService、Callable、Future實現(xiàn)有返回結(jié)果的多線程
?。?)通過線程池創(chuàng)建線程
4.啟動線程方法start和run有什么區(qū)別?
只有調(diào)用了start方法,才會表現(xiàn)出多線程的特性,不同線程的run方法里面的代碼交替執(zhí)行。如果只是調(diào)用run方法,那么代碼還是同步執(zhí)行的,必須等待一個線程的run方法里面的代碼全部執(zhí)行完畢之后,另外一個線程才可以執(zhí)行其run方法里面的代碼。
5.怎么終止一個線程?如何優(yōu)雅地終止線程?
stop終止,不推薦。
6.一個線程的生命周期有哪幾種狀態(tài)?它們之間如何流轉(zhuǎn)的?
NEW:毫無疑問表示的是剛創(chuàng)建的線程,還沒有開始啟動。
RUNNABLE:表示線程已經(jīng)觸發(fā)start方式調(diào)用,線程正式啟動,線程處于運行中狀態(tài)。
BLOCKED:表示線程阻塞,等待獲取鎖,如碰到synchronized、lock等關(guān)鍵字等占用臨界區(qū)的情況,一旦獲取到鎖就進行RUNNABLE狀態(tài)繼續(xù)運行。
WAITING:表示線程處于無限制等待狀態(tài),等待一個特殊的事件來重新喚醒,如通過wait方法進行等待的線程等待一個notify或者notifyAll方法,通過join方法進行等待的線程等待目標(biāo)線程運行結(jié)束而喚醒,一旦通過相關(guān)事件喚醒線程,線程就進入了RUNNABLE狀態(tài)繼續(xù)運行。
TIMED_WAITING:表示線程進入了一個有時限的等待,如sleep(3000),等待3秒后線程重新進行RUNNABLE狀態(tài)繼續(xù)運行。
TERMINATED:表示線程執(zhí)行完畢后,進行終止?fàn)顟B(tài)。需要注意的是,一旦線程通過start方法啟動后就再也不能回到初始NEW狀態(tài),線程終止后也不能再回到RUNNABLE狀態(tài)。
7.線程中的wait和sleep方法有什么區(qū)別?
這個問題常問,sleep方法和wait方法都可以用來放棄CPU一定的時間,不同點在于如果線程持有某個對象的監(jiān)視器,sleep方法不會放棄這個對象的監(jiān)視器,wait方法會放棄這個對象的監(jiān)視器。
8.多線程同步有哪幾種方法?
Synchronized關(guān)鍵字,Lock鎖實現(xiàn),分布式鎖等。
9.多線程有什么用?
1)發(fā)揮多核CPU的優(yōu)勢
隨著工業(yè)的進步,現(xiàn)在的筆記本、臺式機乃至商用的應(yīng)用服務(wù)器至少也都是雙核的,4核、8核甚至16核的也都不少見,如果是單線程的程序,那么在雙核CPU上就浪費了50%,在4核CPU上就浪費了75%。
單核CPU上所謂的"多線程"那是假的多線程,同一時間處理器只會處理一段邏輯,只不過線程之間切換得比較快,看著像多個線程"同時"運行罷了。
多核CPU上的多線程才是真正的多線程,它能讓你的多段邏輯同時工作,多線程,可以真正發(fā)揮出多核CPU的優(yōu)勢來,達(dá)到充分利用CPU的目的。
2)防止阻塞
從程序運行效率的角度來看,單核CPU不但不會發(fā)揮出多線程的優(yōu)勢,反而會因為在單核CPU上運行多線程導(dǎo)致線程上下文的切換,而降低程序整體的效率。
但是單核CPU我們還是要應(yīng)用多線程,就是為了防止阻塞。試想,如果單核CPU使用單線程,那么只要這個線程阻塞了,比方說遠(yuǎn)程讀取某個數(shù)據(jù)吧,對端遲遲未返回又沒有設(shè)置超時時間,那么你的整個程序在數(shù)據(jù)返回回來之前就停止運行了。
多線程可以防止這個問題,多條線程同時運行,哪怕一條線程的代碼執(zhí)行讀取數(shù)據(jù)阻塞,也不會影響其它任務(wù)的執(zhí)行。
3)便于建模
這是另外一個沒有這么明顯的優(yōu)點了。假設(shè)有一個大的任務(wù)A,單線程編程,那么就要考慮很多,建立整個程序模型比較麻煩。但是如果把這個大的任務(wù)A分解成幾個小任務(wù),任務(wù)B、任務(wù)C、任務(wù)D,分別建立程序模型,并通過多線程分別運行這幾個任務(wù),那就簡單很多了。
10.多線程之間如何進行通信?
wait/notify

以上就是動力節(jié)點Java培訓(xùn)機構(gòu)小編介紹的“2020年Java多線程面試題大全”的內(nèi)容,希望對大家有幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務(wù)。
相關(guān)推薦
相關(guān)閱讀