Java线程面试题,值得一看!
1) 什么是線程?
線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。程序員可以通過它進行多處理器編程,你可以使用多線程對運算密集型任務提速。比如,如果一個線程完成一個任務要100毫秒,那么用十個線程完成該任務只需10毫秒。
2) 線程和進程有什么區別?
一個進程是一個獨立(self contained)的運行環境,它可以被看作一個程序或者一個應用。而線程是在進程中執行的一個任務。線程是進程的子集,一個進程可以有很多線程,每條線程并行執行不同的任務。不同的進程使用不同的內存空間,而所有的線程共享一片相同的內存空間。別把它和棧內存搞混,每個線程都擁有單獨的棧內存用來存儲本地數據。
3) 如何在Java中實現線程?
有兩種創建線程的方法:一是實現Runnable接口,然后將它傳遞給Thread的構造函數,創建一個Thread對象;二是直接繼承Thread類。
4) 用Runnable還是Thread?
這個問題是上題的后續,大家都知道我們可以通過繼承Thread類或者調用Runnable接口來實現線程,問題是,那個方法更好呢?什么情況下使用它?這個問題很容易回答,如果你知道Java不支持類的多重繼承,但允許你調用多個接口。所以如果你要繼承其他類,當然是調用Runnable接口好了。更多詳細信息請點擊這里。
6) Thread 類中的start() 和 run() 方法有什么區別?
start()方法被用來啟動新創建的線程,使該被創建的線程狀態變為可運行狀態。當你調用run()方法的時候,只會是在原來的線程中調用,沒有新的線程啟動,start()方法才會啟動新線程。如果我們調用了Thread的run()方法,它的行為就會和普通的方法一樣,直接運行run()方法。為了在新的線程中執行我們的代碼,必須使用Thread.start()方法。
7) Java中Runnable和Callable有什么不同?
Runnable和Callable都代表那些要在不同的線程中執行的任務。Runnable從JDK1.0開始就有了,Callable是在JDK1.5增加的。它們的主要區別是Callable的 call() 方法可以返回值和拋出異常,而Runnable的run()方法沒有這些功能。Callable可以返回裝載有計算結果的Future對象。
? ?為了讓學習變得輕松、高效,今天給大家免費分享一套Java教學資源。幫助大家在成為Java架構師的道路上披荊斬棘。需要資料的歡迎加入學習交流群:9285,05736
8) Java中CyclicBarrier 和 CountDownLatch有什么不同?
CyclicBarrier 和 CountDownLatch 都可以用來讓一組線程等待其它線程。與 CyclicBarrier 不同的是,CountdownLatch 不能重新使用。
9) Java內存模型是什么?
Java內存模型規定和指引Java程序在不同的內存架構、CPU和操作系統間有確定性地行為。它在多線程的情況下尤其重要。Java內存模型對一個線程所做的變動能被其它線程可見提供了保證,它們之間是先行發生關系。這個關系定義了一些規則讓程序員在并發編程時思路更清晰。比如,先行發生關系確保了:
- 線程內的代碼能夠按先后順序執行,這被稱為程序次序規則。
- 對于同一個鎖,一個解鎖操作一定要發生在時間上后發生的另一個鎖定操作之前,也叫做管程鎖定規則。
- 前一個對volatile的寫操作在后一個volatile的讀操作之前,也叫volatile變量規則。
- 一個線程內的任何操作必需在這個線程的start()調用之后,也叫作線程啟動規則。
- 一個線程的所有操作都會在線程終止之前,線程終止規則。
- 一個對象的終結操作必需在這個對象構造完成之后,也叫對象終結規則。
- 可傳遞性
強烈建議大家閱讀《Java并發編程實踐》第十六章來加深對Java內存模型的理解。
10) Java中的volatile 變量是什么?
volatile是一個特殊的修飾符,只有成員變量才能使用它。在Java并發程序缺少同步類的情況下,多線程對成員變量的操作對其它線程是透明的。volatile變量可以保證下一個讀取操作會在前一個寫操作之后發生。線程都會直接從內存中讀取該變量并且不緩存它。這就確保了線程讀取到的變量是同內存中是一致的。
11) 什么是線程安全?Vector是一個線程安全類嗎?
如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。一個線程安全的計數器類的同一個實例對象在被多個線程使用的情況下也不會出現計算失誤。很顯然你可以將集合類分成兩組,線程安全和非線程安全的。Vector 是用同步方法來實現線程安全的, 而和它相似的ArrayList不是線程安全的。
12) Java中什么是競態條件?
在大多數實際的多線程應用中,兩個或兩個以上的線程需要共享對同一數據的存取。如果i線程存取相同的對象,并且每一個線程都調用了一個修改該對象狀態的方法,將會發生什么呢?可以想象,線程彼此踩了對方的腳。根據線程訪問數據的次序,可能會產生訛誤的對象。這樣的情況通常稱為競爭條件。
13) Java中如何停止一個線程?
Java提供了很豐富的API但沒有為停止線程提供API。JDK 1.0本來有一些像stop(), suspend() 和 resume()的控制方法,但是由于潛在的死鎖威脅。因此在后續的JDK版本中他們被棄用了,之后Java API的設計者就沒有提供一個兼容且線程安全的方法來停止一個線程。當run() 或者 call() 方法執行完的時候線程會自動結束,如果要手動結束一個線程,可以用volatile 布爾變量來退出run()方法的循環或者是取消任務來中斷線程。
14) 一個線程運行時發生異常會怎樣?
如果異常沒有被捕獲該線程將會停止執行。Thread.UncaughtExceptionHandler是用于處理未捕獲異常造成線程突然中斷情況的一個內嵌接口。當一個未捕獲異常將造成線程中斷的時候JVM會使用Thread.getUncaughtExceptionHandler()來查詢線程的UncaughtExceptionHandler并將線程和異常作為參數傳遞給handler的uncaughtException()方法進行處理。
15) 如何在兩個線程間共享數據?
你可以通過共享對象來實現這個目的,或者是使用像阻塞隊列這樣并發的數據結構。這篇教程《Java線程間通信》(涉及到在兩個線程間共享對象)用wait和notify方法實現了生產者消費者模型。
16) Java中notify 和 notifyAll有什么區別?
這又是一個刁鉆的問題,因為多線程可以等待單監控鎖,Java API 的設計人員提供了一些方法當等待條件改變的時候通知它們,但是這些方法沒有完全實現。notify()方法不能喚醒某個具體的線程,所以只有一個線程在等待的時候它才有用武之地。而notifyAll()喚醒所有線程并允許他們爭奪鎖確保了至少有一個線程能繼續運行。
17) 為什么wait, notify 和 notifyAll這些方法不在thread類里面?
一個很明顯的原因是JAVA提供的鎖是對象級的而不是線程級的,每個對象都有鎖,通過線程獲得。如果線程需要等待某些鎖那么調用對象中的wait()方法就有意義了。如果wait()方法定義在Thread類中,線程正在等待的是哪個鎖就不明顯了。簡單的說,由于wait,notify和notifyAll都是鎖級別的操作,所以把他們定義在Object類中因為鎖屬于對象。
18) 什么是ThreadLocal變量?
ThreadLocal是Java里一種特殊的變量。每個線程都有一個ThreadLocal就是每個線程都擁有了自己獨立的一個變量,競爭條件被徹底消除了。如果為每個線程提供一個自己獨有的變量拷貝,將大大提高效率。首先,通過復用減少了代價高昂的對象的創建個數。其次,你在沒有使用高代價的同步或者不變性的情況下獲得了線程安全。
19) 什么是FutureTask?
在Java并發程序中FutureTask表示一個可以取消的異步運算。它有啟動和取消運算、查詢運算是否完成和取回運算結果等方法。只有當運算完成的時候結果才能取回,如果運算尚未完成get方法將會阻塞。一個FutureTask對象可以對調用了Callable和Runnable的對象進行包裝,由于FutureTask也是調用了Runnable接口所以它可以提交給Executor來執行。
20) Java中interrupted 和 isInterruptedd方法的區別?
interrupted() 和 isInterrupted()的主要區別是前者會將中斷狀態清除而后者不會。Java多線程的中斷機制是用內部標識來實現的,調用Thread.interrupt()來中斷一個線程就會設置中斷標識為true。當中斷線程調用靜態方法Thread.interrupted()來檢查中斷狀態時,中斷狀態會被清零。而非靜態方法isInterrupted()用來查詢其它線程的中斷狀態且不會改變中斷狀態標識。簡單的說就是任何拋出InterruptedException異常的方法都會將中斷狀態清零。無論如何,一個線程的中斷狀態有有可能被其它線程調用中斷來改變。
總結
以上是生活随笔為你收集整理的Java线程面试题,值得一看!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java enum枚举使用例子
- 下一篇: Java程序员需要掌握哪些技能才能通过大