第一題 談談你對AQS的理解,AQS如何實現(xiàn)可重?鎖?
- AQS是?個JAVA線程同步的框架。是JDK中很多鎖?具的核?實現(xiàn)框架。
- 在AQS中,維護了?個信號量state和?個線程組成的雙向鏈表隊列。其中,這個線程隊列,就是?來給線程排隊的,?state就像是?個紅綠燈,?來控制線程排隊或者放?的。 在不同的場景下,有不?的意義。
- 在可重?鎖這個場景下,state就?來表示加鎖的次數(shù)。0標識?鎖,每加?次鎖,state就加1。釋放鎖state就減1。
第二題. Sychronized的偏向鎖、輕量級鎖、重量級鎖
- 偏向鎖:在鎖對象的對象頭中記錄?下當前獲取到該鎖的線程ID,該線程下次如果?來獲取該鎖就可以直接獲取到了
- 輕量級鎖:由偏向鎖升級?來,當?個線程獲取到鎖后,此時這把鎖是偏向鎖,此時如果有第?個線程來競爭鎖,偏向鎖就會升級為輕量級鎖,之所以叫輕量級鎖,是為了和重量級鎖區(qū)分開來,輕量級鎖底層是通過?旋來實現(xiàn)的,并不會阻塞線程
- 如果?旋次數(shù)過多仍然沒有獲取到鎖,則會升級為重量級鎖,重量級鎖會導致線程阻塞
- ?旋鎖:?旋鎖就是線程在獲取鎖的過程中,不會去阻塞線程,也就?所謂喚醒線程,阻塞和喚醒這兩個步驟都是需要操作系統(tǒng)去進?的,?較消耗時間,?旋鎖是線程通過CAS獲取預期的?個標記,如果沒有獲取到,則繼續(xù)循環(huán)獲取,如果獲取到了則表示獲取到了鎖,這個過程線程?直在運?中,相對??沒有使?太多的操作系統(tǒng)資源,?較輕量。
第三題 CountDownLatch和Semaphore的區(qū)別和底層原理
CountDownLatch表示計數(shù)器,可以給CountDownLatch設置?個數(shù)字,?個線程調(diào)?CountDownLatch的await()將會阻塞,其他線程可以調(diào)?CountDownLatch的countDown()?法來對CountDownLatch中的數(shù)字減?,當數(shù)字被減成0后,所有await的線程都將被喚醒。
對應的底層原理就是,調(diào)?await()?法的線程會利?AQS排隊,?旦數(shù)字被減為0,則會將AQS中排隊的線程依次喚醒。
Semaphore表示信號量,可以設置許可的個數(shù),表示同時允許最多多少個線程使?該信號量,通過acquire()來獲取許可,如果沒有許可可?則線程阻塞,并通過AQS來排隊,可以通過release()?法來釋放許可,當某個線程釋放了某個許可后,會從AQS中正在排隊的第?個線程開始依次喚醒,直到?jīng)]有空閑許可。
第四題 線程池中阻塞隊列的作??為什么是先添加列隊?不是先創(chuàng)建最?線程?
1、?般的隊列只能保證作為?個有限?度的緩沖區(qū),如果超出了緩沖?度,就?法保留當前的任務了,阻塞隊列通過阻塞可以保留住當前想要繼續(xù)?隊的任務。
阻塞隊列可以保證任務隊列中沒有任務時阻塞獲取任務的線程,使得線程進?wait狀態(tài),釋放cpu資源。
阻塞隊列?帶阻塞和喚醒的功能,不需要額外處理,?任務執(zhí)?時,線程池利?阻塞隊列的take?法掛起,從?維持核?線程的存活、不?于?直占?cpu資源
2、在創(chuàng)建新線程的時候,是要獲取全局鎖的,這個時候其它的就得阻塞,影響了整體效率。
就好??個企業(yè)??有10個(core)正式?的名額,最多招10個正式?,要是任務超過正式??數(shù)(task > core)的情況下,??領導(線程池)不是?先擴招??,還是這10?,但是任務可以稍微積壓?下,即先放到隊列去(代價低)。10個正式?慢慢?,遲早會?完的,要是任務還在繼續(xù)增加,超過正式?的加班忍耐極限了(隊列滿了),就的招外包幫忙了(注意是臨時?)要是正式?加上外包還是不能完成任務,那新來的任務就會被領導拒絕了(線程池的拒絕策略)。
第五題 對守護線程的理解
守護線程:為所有?守護線程提供服務的線程;任何?個守護線程都是整個JVM中所有?守護線程的保姆;
守護線程類似于整個進程的?個默默?聞的?嘍嘍;它的?死?關重要,它卻依賴整個進程?運?;哪天其他線程結束了,沒有要執(zhí)?的了,程序就結束了,理都沒理守護線程,就把它中斷了;
注意: 由于守護線程的終?是?身?法控制的,因此千萬不要把IO、File等重要操作邏輯分配給它;因為它不靠譜;
守護線程的作?是什么?
舉例, GC垃圾回收線程:就是?個經(jīng)典的守護線程,當我們的程序中不再有任何運?的Thread,程序就不會再產(chǎn)?垃圾,垃圾回收器也就?事可做,所以當垃圾回收線程是JVM上僅剩的線程時,垃圾回收線程會?動離開。它始終在低級別的狀態(tài)中運?,?于實時監(jiān)控和管理系統(tǒng)中的可回收資源。
應?場景:(1)來為其它線程提供服務?持的情況;(2) 或者在任何情況下,程序結束時,這個線程必須正常且?刻關閉,就可以作為守護線程來使?;反之,如果?個正在執(zhí)?某個操作的線程必須要正確地關閉掉否則就會出現(xiàn)不好的后果的話,那么這個線程就不能是守護線程,?是?戶線程。通常都是些關鍵的事務,??說,數(shù)據(jù)庫錄?或者更新,這些操作都是不能中斷的。
thread.setDaemon(true)必須在thread.start()之前設置,否則會跑出?個IllegalThreadStateException異常。你不能把正在運?的常規(guī)線程設置為守護線程。
在Daemon線程中產(chǎn)?的新線程也是Daemon的。
守護線程不能?于去訪問固有資源,?如讀寫操作或者計算邏輯。因為它會在任何時候甚?在?個操作的中間發(fā)?中斷。
Java?帶的多線程框架,?如ExecutorService,會將守護線程轉(zhuǎn)換為?戶線程,所以如果要使?后臺線程就不能?Java的線程池。文章來源:http://www.zghlxwxcb.cn/news/detail-829246.html
如果我的內(nèi)容對你有幫助,請點贊,評論,收藏。創(chuàng)作不易,大家的支持就是我堅持下去的動力文章來源地址http://www.zghlxwxcb.cn/news/detail-829246.html
到了這里,關于每日五道java面試題之java基礎篇(十二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!