溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java的多線程面試題是什么

發(fā)布時間:2022-01-05 15:29:05 來源:億速云 閱讀:119 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“Java的多線程面試題是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java的多線程面試題是什么”吧!

121,什么是線程?

        線程是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位,它被包含在進(jìn)程之中,是進(jìn)程中的實際運(yùn)作單位。程序員可以通過它進(jìn)行多處理器編程,你可以使用多線程對運(yùn)算密集型任務(wù)提速。比如,如果一個線程完成一個任務(wù)要100毫秒,那么用十個線程完成改任務(wù)只需10毫秒。

122,線程和進(jìn)程有什么區(qū)別?

        線程是進(jìn)程的子集,一個進(jìn)程可以有很多線程,每條線程并行執(zhí)行不同的任務(wù)。不同的進(jìn)程使用不同的內(nèi)存空間,而所有的線程共享一片相同的內(nèi)存空間。每個線程都擁有單獨(dú)的棧內(nèi)存用來存儲本地數(shù)據(jù)。

123,如何在Java中實現(xiàn)線程?

        兩種方式:java.lang.Thread 類的實例就是一個線程但是它需要調(diào)用java.lang.Runnable接口來執(zhí)行,由于線程類本身就是調(diào)用的Runnable接口所以你可以繼承java.lang.Thread 類或者直接調(diào)用Runnable接口來重寫run()方法實現(xiàn)線程。

124,Java 關(guān)鍵字volatile 與 synchronized 作用與區(qū)別?

    1,volatile
    它所修飾的變量不保留拷貝,直接訪問主內(nèi)存中的。
           在Java內(nèi)存模型中,有main memory,每個線程也有自己的memory (例如寄存器)。為了性能,一個線程會在自己的memory中保持要訪問的變量的副本。這樣就會出現(xiàn)同一個變 量在某個瞬間,在一個線程的memory中的值可能與另外一個線程memory中的值,或者main memory中的值不一致的情況。 一個變量聲明為volatile,就意味著這個變量是隨時會被其他線程修改的,因此不能將它c(diǎn)ache在線程memory中。
    2,synchronized

    當(dāng)它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執(zhí)行該段代碼。

         一、當(dāng)兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當(dāng)前線程執(zhí)行完這個代碼塊以后才能執(zhí)行該代碼塊。

         二、然而,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。

         三、尤其關(guān)鍵的是,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。

         四、當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結(jié)果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。

         五、以上規(guī)則對其它對象鎖同樣適用.

125,有哪些不同的線程生命周期?

        當(dāng)我們在Java程序中新建一個線程時,它的狀態(tài)是New。當(dāng)我們調(diào)用線程的start()方法時,狀態(tài)被改變?yōu)?em>Runnable。線程調(diào)度器會為Runnable線程池中的線程分配CPU時間并且講它們的狀態(tài)改變?yōu)?em>Running。其他的線程狀態(tài)還有Waiting,Blocked 和Dead

126,你對線程優(yōu)先級的理解是什么?

        每一個線程都是有優(yōu)先級的,一般來說,高優(yōu)先級的線程在運(yùn)行時會具有優(yōu)先權(quán),但這依賴于線程調(diào)度的實現(xiàn),這個實現(xiàn)是和操作系統(tǒng)相關(guān)的(OS dependent)。我們可以定義線程的優(yōu)先級,但是這并不能保證高優(yōu)先級的線程會在低優(yōu)先級的線程前執(zhí)行。線程優(yōu)先級是一個int變量(從1-10),1代表最低優(yōu)先級,10代表最高優(yōu)先級。

127,什么是死鎖(Deadlock)?如何分析和避免死鎖?

        死鎖是指兩個以上的線程永遠(yuǎn)阻塞的情況,這種情況產(chǎn)生至少需要兩個以上的線程和兩個以上的資源。

        分析死鎖,我們需要查看Java應(yīng)用程序的線程轉(zhuǎn)儲。我們需要找出那些狀態(tài)為BLOCKED的線程和他們等待的資源。每個資源都有一個唯一的id,用這個id我們可以找出哪些線程已經(jīng)擁有了它的對象鎖。

        避免嵌套鎖,只在需要的地方使用鎖和避免無限期等待是避免死鎖的通常辦法。

128,什么是線程安全?Vector是一個線程安全類嗎?

        如果你的代碼所在的進(jìn)程中有多個線程在同時運(yùn)行,而這些線程可能會同時運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的。一個線程安全的計數(shù)器類的同一個實例對象在被多個線程使用的情況下也不會出現(xiàn)計算失誤。很顯然你可以將集合類分成兩組,線程安全和非線程安全的。Vector 是用同步方法來實現(xiàn)線程安全的, 而和它相似的ArrayList不是線程安全的。

129,Java中如何停止一個線程?

        Java提供了很豐富的API但沒有為停止線程提供API。JDK 1.0本來有一些像stop(), suspend() 和 resume()的控制方法但是由于潛在的死鎖威脅因此在后續(xù)的JDK版本中他們被棄用了,之后Java API的設(shè)計者就沒有提供一個兼容且線程安全的方法來停止一個線程。當(dāng)run() 或者 call() 方法執(zhí)行完的時候線程會自動結(jié)束,如果要手動結(jié)束一個線程,你可以用volatile 布爾變量來退出run()方法的循環(huán)或者是取消任務(wù)來中斷線程

130,什么是ThreadLocal?

        ThreadLocal用于創(chuàng)建線程的本地變量,我們知道一個對象的所有線程會共享它的全局變量,所以這些變量不是線程安全的,我們可以使用同步技術(shù)。但是當(dāng)我們不想使用同步的時候,我們可以選擇ThreadLocal變量。

        每個線程都會擁有他們自己的Thread變量,它們可以使用get()\set()方法去獲取他們的默認(rèn)值或者在線程內(nèi)部改變他們的值。ThreadLocal實例通常是希望它們同線程狀態(tài)關(guān)聯(lián)起來是private static屬性。

131,Sleep()、suspend()和wait()之間有什么區(qū)別?

        Thread.sleep()使當(dāng)前線程在指定的時間處于“非運(yùn)行”(Not Runnable)狀態(tài)。線程一直持有對象的監(jiān)視器。比如一個線程當(dāng)前在一個同步塊或同步方法中,其它線程不能進(jìn)入該塊或方法中。如果另一線程調(diào)用了interrupt()方法,它將喚醒那個“睡眠的”線程。

        注意:sleep()是一個靜態(tài)方法。這意味著只對當(dāng)前線程有效,一個常見的錯誤是調(diào)用t.sleep(),(這里的t是一個不同于當(dāng)前線程的線程)。即便是執(zhí)行t.sleep(),也是當(dāng)前線程進(jìn)入睡眠,而不是t線程。t.suspend()是過時的方法,使用suspend()導(dǎo)致線程進(jìn)入停滯狀態(tài),該線程會一直持有對象的監(jiān)視器,suspend()容易引起死鎖問題。

        object.wait()使當(dāng)前線程出于“不可運(yùn)行”狀態(tài),和sleep()不同的是wait是object的方法而不是thread。調(diào)用object.wait()時,線程先要獲取這個對象的對象鎖,當(dāng)前線程必須在鎖對象保持同步,把當(dāng)前線程添加到等待隊列中,隨后另一線程可以同步同一個對象鎖來調(diào)用object.notify(),這樣將喚醒原來等待中的線程,然后釋放該鎖?;旧蟱ait()/notify()與sleep()/interrupt()類似,只是前者需要獲取對象鎖。

132,什么是線程餓死,什么是活鎖?

        當(dāng)所有線程阻塞,或者由于需要的資源無效而不能處理,不存在非阻塞線程使資源可用。JavaAPI中線程活鎖可能發(fā)生在以下情形:

        1,當(dāng)所有線程在程序中執(zhí)行Object.wait(0),參數(shù)為0的wait方法。程序?qū)l(fā)生活鎖直到在相應(yīng)的對象上有線程調(diào)用Object.notify()或者Object.notifyAll()。

        2,當(dāng)所有線程卡在無限循環(huán)中。

133,什么是Java Timer類?如何創(chuàng)建一個有特定時間間隔的任務(wù)?

        java.util.Timer是一個工具類,可以用于安排一個線程在未來的某個特定時間執(zhí)行。Timer類可以用安排一次性任務(wù)或者周期任務(wù)。

        java.util.TimerTask是一個實現(xiàn)了Runnable接口的抽象類,我們需要去繼承這個類來創(chuàng)建我們自己的定時任務(wù)并使用Timer去安排它的執(zhí)行。

134,Java中的同步集合與并發(fā)集合有什么區(qū)別?

        同步集合與并發(fā)集合都為多線程和并發(fā)提供了合適的線程安全的集合,不過并發(fā)集合的可擴(kuò)展性更高。

        在Java1.5之前程序員們只有同步集合來用且在多線程并發(fā)的時候會導(dǎo)致爭用,阻礙了系統(tǒng)的擴(kuò)展性。

        Java5介紹了并發(fā)集合像ConcurrentHashMap,不僅提供線程安全還用鎖分離和    內(nèi)部分區(qū)等現(xiàn)代技術(shù)提高了可擴(kuò)展性。

135,同步方法和同步塊,哪個是更好的選擇?

        同步塊是更好的選擇,因為它不會鎖住整個對象(當(dāng)然你也可以讓它鎖住整個對象)。同步方法會鎖住整個對象,哪怕這個類中有多個不相關(guān)聯(lián)的同步塊,這通常會導(dǎo)致他們停止執(zhí)行并需要等待獲得這個對象上的鎖。

136,什么是線程池? 為什么要使用它?

        創(chuàng)建線程要花費(fèi)昂貴的資源和時間,如果任務(wù)來了才創(chuàng)建線程那么響應(yīng)時間會變長,而且一個進(jìn)程能創(chuàng)建的線程數(shù)有限。

        為了避免這些問題,在程序啟動的時候就創(chuàng)建若干線程來響應(yīng)處理,它們被稱為線程池,里面的線程叫工作線程。

        從JDK1.5開始,Java API提供了Executor框架讓你可以創(chuàng)建不同的線程池。比如單線程池,每次處理一個任務(wù);數(shù)目固定的線程池或者是緩存線程池(一個適合很多生存期短的任務(wù)的程序的可擴(kuò)展線程池)。

137,Java中invokeAndWait 和 invokeLater有什么區(qū)別?

        這兩個方法是Swing API 提供給Java開發(fā)者用來從當(dāng)前線程而不是事件派發(fā)線程更新GUI組件用的。InvokeAndWait()同步更新GUI組件,比如一個進(jìn)度條,一旦進(jìn)度更新了,進(jìn)度條也要做出相應(yīng)改變。如果進(jìn)度被多個線程跟蹤,那么就調(diào)用invokeAndWait()方法請求事件派發(fā)線程對組件進(jìn)行相應(yīng)更新。而invokeLater()方法是異步調(diào)用更新組件的。

138,多線程中的忙循環(huán)是什么?

        忙循環(huán)就是程序員用循環(huán)讓一個線程等待,不像傳統(tǒng)方法wait(), sleep() 或 yield() 它們都放棄了CPU控制,而忙循環(huán)不會放棄CPU,它就是在運(yùn)行一個空循環(huán)。這么做的目的是為了保留CPU緩存。

        在多核系統(tǒng)中,一個等待線程醒來的時候可能會在另一個內(nèi)核運(yùn)行,這樣會重建緩存。為了避免重建緩存和減少等待重建的時間就可以使用它了。

感謝各位的閱讀,以上就是“Java的多線程面試題是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Java的多線程面試題是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI