首頁 >Java >Java面試題 >java多執行緒面試題目

java多執行緒面試題目

(*-*)浩
(*-*)浩原創
2019-12-11 15:05:352934瀏覽

java多執行緒面試題目

什麼是執行緒?

執行緒是作業系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。程式設計師可以透過它進行多處理器編程,你可以使用多執行緒對運算密集型任務提速。       (建議學習:java面試題目

例如,如果一個執行緒完成一個任務要100毫秒,那麼用十個執行緒完成改任務只需10毫秒。

執行緒和行程有什麼差別?

線程是進程的子集,一個進程可以有很多線程,每個線程並行執行不同的任務。不同的行程使用不同的記憶體空間,而所有的執行緒共享一片相同的記憶體空間。每個執行緒都擁有單獨的棧記憶體用來儲存本地資料。

如何在Java中實作執行緒?

兩種方式:java.lang.Thread 類別的實例就是一個執行緒但是它需要呼叫java.lang.Runnable介面來執行,由於執行緒類別本身就是一個呼叫的Runnable介面所以你可以繼承java.lang.Thread 類別或直接呼叫Runnable介面來重寫run()方法實作執行緒。

Java 關鍵字volatile 與 synchronized 作用與差異?

1,volatile

它所修飾的變數不保留拷貝,直接存取主記憶體中的。

在Java記憶體模型中,有main memory,每個執行緒也有自己的memory (例如暫存器)。為了效能,一個執行緒會在自己的memory中保持要存取的變數的副本。

這樣就會出現同一個變 量在某個瞬間,在一個執行緒的memory中的值可能與另外一個執行緒memory中的值,或是main memory中的值不一致的情況。

 一個變數宣告為volatile,就表示這個變數是隨時會被其他執行緒修改的,因此不能將它cache在執行緒memory中。

2,synchronized

當它用來修飾一個方法或一個程式碼區塊的時候,能夠保證在同一時刻最多只有一個執行緒執行該段程式碼。

一、當兩個並發線程訪問同一個物件object中的這個synchronized(this)同步程式碼區塊時,一個時間內只能有一個執行緒來執行。另一個執行緒必須等待目前執行緒執行完這個程式碼區塊以後才能執行該程式碼區塊。

二、然而,當一個執行緒存取object的一個synchronized(this)同步程式碼區塊時,另一個執行緒仍然可以存取該object中的非synchronized(this)同步程式碼區塊。

三、尤其關鍵的是,當一個執行緒存取object的一個synchronized(this)同步程式碼區塊時,其他執行緒對object中所有其它synchronized(this)同步程式碼區塊的存取將被阻塞。

四、當一個執行緒存取object的一個synchronized(this)同步程式碼區塊時,它就獲得了這個object的物件鎖定。結果,其它執行緒對該object物件所有同步程式碼部分的存取都被暫時阻塞。

五、以上規則對其它物件鎖定同樣適用.

有哪些不同的執行緒生命週期?

當我們在Java程式中新一個執行緒時,它的狀態是New。當我們呼叫線程的start()方法時,狀態被改變為Runnable。執行緒調度器會為Runnable執行緒池中的執行緒分配CPU時間並且講它們的狀態改變為Running。其他的執行緒狀態還有Waiting,Blocked 和Dead。

你對執行緒優先權的理解是什麼?

每一個執行緒都是有優先權的,一般來說,高優先權的執行緒在運行時會具有優先權,但這依賴於執行緒調度的實現,這個實現是和作業系統相關的(OS dependent)。

我們可以定義執行緒的優先權,但是這並不能保證高優先權的執行緒會在低優先權的執行緒前執行。執行緒優先權是一個int變數(從1-10),1代表最低優先權,10代表最高優先權。

什麼是死鎖(Deadlock)?如何分析和避免死鎖?

死鎖是指兩個以上的執行緒永遠阻塞的情況,這種情況產生至少需要兩個以上的執行緒和兩個以上的資源。

分析死鎖,我們需要查看Java應用程式的執行緒轉儲。我們需要找出那些狀態為BLOCKED的執行緒和他們等待的資源。每個資源都有一個唯一的id,用這個id我們可以找出哪些執行緒已經擁有了它的物件鎖。

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

什麼是線程安全? Vector是一個執行緒安全類別嗎?

如果你的程式碼所在的進程中有多個執行緒在同時運行,而這些執行緒可能會同時運行這段程式碼。如果每次運行結果和單執行緒運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。

一個執行緒安全的計數器類別的同一個實例物件在被多個執行緒使用的情況下也不會出現計算失誤。很顯然你可以將集合類別分成兩組,線程安全和非線程安全的。 Vector 是用同步方法來實現線程安全的, 而和它相似的ArrayList不是線程安全的。

Java中如何停止一個執行緒?

Java提供了豐富的API但沒有為停止執行緒提供API。 JDK 1.0本來有一些像stop(), suspend() 和resume()的控制方法但是由於潛在的死鎖威脅因此在後續的JDK版本中他們被棄用了,之後Java API的設計者就沒有提供一個相容且線程安全的方法來停止一個線程。

當run() 或call() 方法執行完的時候線程會自動結束,如果要手動結束一個線程,你可以用volatile 布爾變量來退出run()方法的循環或者是取消任務來中斷線程

什麼是ThreadLocal?

ThreadLocal用於創建線程的本地變量,我們知道一個物件的所有線程會共享它的全域變量,所以這些變量不是線程安全的,我們可以使用同步技術。但是當我們不想使用同步的時候,我們可以選擇ThreadLocal變數。

每個執行緒都會擁有自己的Thread變量,它們可以使用get()\set()方法去取得他們的預設值或在執行緒內部改變他們的值。 ThreadLocal實例通常是希望它們同線程狀態關聯起來是private static屬性。

Sleep()、suspend()和wait()有什麼差別?

Thread.sleep()使目前執行緒在指定的時間處於「非運行」(Not Runnable)狀態。線程一直持有物件的監視器。例如一個執行緒目前在一個同步區塊或同步方法中,其它執行緒不能進入該區塊或方法中。如果另一個執行緒呼叫了interrupt()方法,它將喚醒那個「睡眠的」執行緒。

注意:sleep()是一個靜態方法。這意味著只對目前執行緒有效,一個常見的錯誤是呼叫t.sleep(),(這裡的t是一個不同於目前執行緒的執行緒)。

即使是執行t.sleep(),也是目前執行緒進入睡眠,而不是t執行緒。 t.suspend()是一種過時的方法,使用suspend()導致執行緒進入停滯狀態,該執行緒會一直持有物件的監視器,suspend()容易造成死鎖問題。

object.wait()使目前執行緒出於「不可運行」狀態,和sleep()不同的是wait是object的方法而不是thread。當呼叫object.wait()時,執行緒先要取得這個物件的物件鎖,目前執行緒必須在鎖物件保持同步,把目前執行緒加入等待佇列。

隨後另一個線程可以同步同一個物件鎖定來呼叫object.notify(),這樣將喚醒原來等待中的線程,然後釋放該鎖定。基本上wait()/notify()與sleep()/interrupt()類似,只是前者需要取得物件鎖定。

什麼是執行緒餓死,什麼是活鎖?

當所有執行緒阻塞,或由於需要的資源無效而不能處理,不存在非阻塞執行緒使資源可用。 JavaAPI中執行緒活鎖可能發生在下列情形:

1,當所有執行緒在程式中執行Object.wait(0),參數為0的wait方法。程式將發送生活鎖直到在對應的物件上有執行緒呼叫Object.notify()或Object.notifyAll()。

2,當所有執行緒卡在無限循環中。

什麼是Java Timer類別?如何建立一個有特定時間間隔的任務?

java.util.Timer是一個工具類,可以用來安排一個執行緒在未來的某個特定時間執行。 Timer類別可以用安排一次性任務或週期任務。

java.util.TimerTask是一個實作了Runnable介面的抽象類,我們需要去繼承這個類別來創建我們自己的定時任務並使用Timer去安排它的執行。

Java中的同步集合與並發集合有什麼不同?

同步集合與並發集合都為多線程和並發提供了合適的線程安全的集合,不過並發集合的可擴展性更高。

在Java1.5之前程式設計師們只有同步集合來用且在多執行緒並發的時候會導致爭用,阻礙了系統的擴充性。

Java5介紹了並發集合像ConcurrentHashMap,不僅提供線程安全還用鎖定分離和    內部分區等現代技術提高了可擴展性。

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

同步區塊是更好的選擇,因為它不會鎖住整個物件(當然你也可以讓它鎖住整個物件)。同步方法會鎖住整個對象,即使這個類別中有多個不相關聯的同步區塊,這通常會導致他們停止執行並需要等待獲得這個物件上的鎖。

什麼是執行緒池?為什麼要使用它?

建立執行緒要花昂貴的資源和時間,如果任務來了才創建執行緒那麼回應時間會變長,而且一個行程能建立的執行緒數有限。

為了避免這些問題,在程式啟動的時候就創建若干執行緒來回應處理,它們稱為執行緒池,裡面的執行緒叫做工作執行緒。

從JDK1.5開始,Java API提供了Executor框架讓你可以建立不同的執行緒池。例如單執行緒池,每次處理一個任務;數目固定的執行緒池或是快取執行緒池(一個適合很多生存期短的任務的程式的可擴展執行緒池)。

Java中invokeAndWait 和 invokeLater有什麼差別?

這兩個方法是Swing API 提供給Java開發者用來從目前執行緒而不是事件派發執行緒更新GUI元件用的。 InvokeAndWait()同步更新GUI元件,例如進度條,一旦進度更新了,進度條也要做出對應改變。

如果進度被多個執行緒追蹤,那麼就呼叫invokeAndWait()方法請求事件派發執行緒對元件進行對應更新。而invokeLater()方法是非同步呼叫更新元件的。

多執行緒中的忙迴圈是什麼?

忙迴圈就是程式設計師用迴圈讓一個執行緒等待,不像傳統方法wait(), sleep() 或yield() 它們都放棄了CPU控制,而忙循環不會放棄CPU,它就是在運行一個空循環。這麼做的目的是為了保留CPU快取。

在多核心系統中,一個等待執行緒醒來的時候可能會在另一個核心運行,這樣會重建快取。為了避免重建快取和減少等待重建的時間就可以使用它了。

以上是java多執行緒面試題目的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn