Java常用面試題之Java多執行緒(十三)

Mr_TXQ發表於2020-10-14

121,什麼是執行緒?

	執行緒是作業系統能夠進行運算排程的最小單位,它被包含在程式之中,是程式中的實際運作單位。程式設計師可以通
	過它進行多處理器程式設計,可以使用多執行緒對運算密集型任務提速。比如,如果一個執行緒完成一個任務要100毫秒,
	那麼用十個執行緒完成該任務只需要10毫秒

122,執行緒和程式有什麼區別?

	在作業系統中,程式是程式的一次執行。在執行過程中,程式會申請,持有或釋放作業系統資源。
	執行緒和程式非常相似,又被稱為輕量級程式。一個程式可擁有多個執行緒,這些執行緒共享此程式所持有的系統資源。
	排程、執行的基本單位是執行緒,資源分配的基本單位是程式

123,如何在Java中實現執行緒?

	一種是繼承Thread類,另一種是實現Runnable介面,當然使用Runnable最終還是要用到Thread

124,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物件所有同步程式碼部分的訪問都被暫時阻塞。
	五、以上規則對其它物件鎖同樣適用

 125,有哪些不同的執行緒生命週期?
 
	在Java程式中新建一個執行緒時,它的狀態是New。當我們呼叫執行緒的start()方法時,狀態被改變為Runnable。
	執行緒排程器會為Runnable執行緒池中的執行緒分配CPU時間並且將它們的狀態改變為Running。其他的執行緒狀態還有
	Waiting,Blocked和Dead

126,你對執行緒優先順序的理解是什麼?

	每一個執行緒都是有優先順序的,一般來說,高優先順序的執行緒在執行時會具有優先權,但這依賴於執行緒排程的實現,
	這個實現是和作業系統相關的(OSdependent)。我們可以定義執行緒的優先順序,但是這並不能保證高優先順序的執行緒
	會在低優先順序的執行緒前執行。執行緒優先順序是一個int變數(1-10)1代表最低優先順序,10代表最高優先順序

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

	死鎖是指兩個以上的執行緒永遠阻塞的情況,這種情況產生至少需要兩個以上的執行緒和兩個以上的資源。
	分析死鎖,檢視Java應用程式的執行緒轉儲。找出那些狀態為Blocked的執行緒和它們等待的資源。每個資源都有一
	個唯一的id,用這個id可以找出哪些執行緒已經擁有了它的物件鎖。
	避免巢狀鎖,只在需要的地方使用鎖和避免無限期等待是避免死鎖的通常辦法

128,什麼是執行緒安全?Vector是一個執行緒安全類嗎? 

	如果你的程式碼所在的程式中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和
	單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。一個執行緒安全的計數
	器類的同一個例項物件在被多個執行緒使用的情況下也不會出現計算失誤。很顯然你可以將集合類分成兩組,執行緒
	安全和非執行緒安全的。Vector 是用同步方法來實現執行緒安全的, 而和它相似的ArrayList不是執行緒安全的

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

	Java提供了很豐富的API但沒有為停止執行緒提供APIJDK 1.0本來有一些像stop(), suspend()resume()
	的控制方法但是由於潛在的死鎖威脅因此在後續的JDK版本中他們被棄用了,之後Java API的設計者就沒有提供
	一個相容且執行緒安全的方法來停止一個執行緒。當run() 或者 call() 方法執行完的時候執行緒會自動結束,如果要
	手動結束一個執行緒,你可以用volatile 布林變數來退出run()方法的迴圈或者是取消任務來中斷執行緒
 
130,什麼是ThreadLocal?

	ThreadLocal用於建立執行緒的本地變數,我們知道一個物件的所有執行緒會共享它的全域性變數,所以這些變數不是
	執行緒安全的,我們可以使用同步技術。但是當我們不想使用同步的時候,我們可以選擇ThreadLocal變數。
	每個執行緒都會擁有他們自己的Thread變數,它們可以使用get()\set()方法去獲取他們的預設值或者線上程內
	部改變他們的值。ThreadLocal例項通常是希望它們同執行緒狀態關聯起來是private static屬性
        
131,Sleep()、suspend()和wait()之間有什麼區別?

	sleep()會讓執行緒停止,但此時執行緒仍然持有鎖,並不會釋放這些鎖。另外一般使用時都會讓執行緒停止指定的時
	間如1000毫秒
	suspend()會掛起執行緒直到另一個執行緒resume。但由於掛起時仍然會持有鎖,很容易造成死鎖。
	wait()也會讓執行緒停止,但此時執行緒釋放所持有的鎖。一般和notify()配合使用

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

	當所有執行緒阻塞,或者由於需要的資源無效而不能處理,不存在非阻塞執行緒使資源可用。JavaAPI中執行緒活鎖可
	能發生在以下情形:
	1,當所有執行緒在程式中執行Object.wait(0),引數為0的wait方法。程式將發生活鎖直到在相應的物件上有線
	程呼叫Object.notify()或者Object.notifyAll()2,當所有執行緒卡在無限迴圈中
        
133,什麼是Java Timer類?如何建立一個有特定時間間隔的任務?

    java.util.Timer是一個工具類,可以用於安排一個執行緒在未來的某個特定時間執行。Timer類可以用安排一次
    性任務或者週期任務。
    java.util.TimerTask是一個實現了Runnable介面的抽象類,我們需要去繼承這個類來建立我們自己的定時任
    務並使用Timer去安排它的執行
        
134,Java中的同步集合與併發集合有什麼區別?

	同步集合與併發集合都為多執行緒和併發提供了合適的執行緒安全的集合,不過併發集合的可擴充套件性更高。
    在Java1.5之前程式設計師們只有同步集合來用且在多執行緒併發的時候會導致爭用,阻礙了系統的擴充套件性。
    Java5介紹了併發集合像ConcurrentHashMap,不僅提供執行緒安全還用鎖分離和    內部分割槽等現代技術提高了
    可擴充套件性
        
135,同步方法和同步塊,哪個是更好的選擇?

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

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

	 建立執行緒要花費昂貴的資源和時間,如果任務來了才建立執行緒那麼響應時間會變長,而且一個程式能建立的線
	 程數有限。
	 為了避免這些問題,在程式啟動的時候就建立若干執行緒來響應處理,它們被稱為執行緒池,裡面的執行緒叫工作
	 執行緒。
	 從JDK1.5開始,Java API提供了Executor框架讓你可以建立不同的執行緒池。比如單執行緒池,每次處理一個
	 任務;數目固定的執行緒池或者是快取執行緒池(一個適合很多生存期短的任務的程式的可擴充套件執行緒池)
        
137,Java中invokeAndWait 和 invokeLater有什麼區別?

	這兩個方法是Swing API 提供給Java開發者用來從當前執行緒而不是事件派發執行緒更新GUI元件用的。
	InvokeAndWait()同步更新GUI元件,比如一個進度條,一旦進度更新了,進度條也要做出相應改變。如果進度
	被多個執行緒跟蹤,那麼就呼叫invokeAndWait()方法請求事件派發執行緒對元件進行相應更新。而invokeLater()
	方法是非同步呼叫更新元件的

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

	忙迴圈就是程式設計師用迴圈讓一個執行緒等待,不像傳統方法wait(), sleep()yield() 它們都放棄了CPU控制,
	而忙迴圈不會放棄CPU,它就是在執行一個空迴圈。這麼做的目的是為了保留CPU快取。
	在多核系統中,一個等待執行緒醒來的時候可能會在另一個核心執行,這樣會重建快取。為了避免重建快取和減少
	等待重建的時間就可以使用它了

上一篇: Java常用面試題之資料庫篇(十二)
下一篇: Java常用面試題之Java泛型篇(十四)

相關文章