Java基礎面試題之多線程一

1.什麼是線程?

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

2.什麼是線程安全?Vector是一個線程安全類嗎?

如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼,如果每次運行的結果和單線程運行的結果是一樣的,而且其他變量的值和預期的一樣,就是線程安全的。一個線程安全的計數器類的同一個實例對象在被多個線程使用的情況下也不會出現計算失誤。Vector是線程安全的,和它相似的ArrayList則是線程不安全的

3.進程和線程的區別是什麼?

參考文章:

      進程與線程

4.創建線程有幾種不同的方式?

有四種方法

繼承Thread類

實現Runnable接口

通過Callable和Future創建

使用Executor框架來創建線程池

參考文章:

        Java中創建線程的四種方法

5.什麼是Callable、Future和FutureTask?

Callable類似於Runnable接口,從名字就可以看出來,但是Runnable不會返回結果,並且無法拋出返回結果的異常,Callable的功能更強大一些,被線程執行後,可以返回值,這個返回值可以被Future拿到

可以認爲Callable是帶有返回值的Runnable

Future就是對於具體的Callable或者Runnable任務的執行結果進行取消、查詢是否完成、獲取結果,必要是可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。因爲Future只是一個接口,所以是無法直接用來創建對象使用的,因此就有了FutureTask,FutureTask類實現了RunnableFuture接口,而RunnableFuture接口繼承了Runnable接口和Future接口,所以FutureTask既可以作爲Runnable被線程執行,又可以作爲Future得到Callable的返回值

Future接口表示異步任務,是還沒有完成的任務給出的未來結果。所以說Callable用來產生結果,Future用來獲取結果

6.什麼是Executor框架?

Executor框架是一個根據一組執行策略調用,調度,執行和控制的異步任務的框架。

無限制的創建線程會引起應用程序內存溢出。所以創建一個線程池是個更好的的解決方案,因爲可以限制線程的數量並且可以回收再利用這些線程。利用Executor框架可以非常方便的創建一個線程池

7.爲什麼使用Executor框架?

每次執行任務創建線程 new Thread()比較消耗性能,創建一個線程是比較耗時、耗資源的

調用 new Thread()創建的線程缺乏管理,被稱爲野線程,而且可以無限制的創建,線程之間的相互競爭會導致過多佔用系統資源而導致系統癱瘓,還有線程之間的頻繁交替也會消耗很多系統資源

接使用new Thread() 啓動的線程不利於擴展,比如定時執行、定期執行、定時定期執行、線程中斷等都不便實現

8.在Java中Executor和Executors的區別

Executors工具類的不同方法按照我們的需求創建了不同的線程池,來滿足業務的需求

Executor 接口對象能執行我們的線程任務

ExecutorService接口繼承了Executor接口並進行了擴展,提供了更多的方法我們能獲得任務執行的狀態並且可以獲取任務的返回值 

使用ThreadPoolExecutor 可以創建自定義線程池

Future 表示異步計算的結果,他提供了檢查計算是否完成的方法,以等待計算的完成,並可以使用get()方法獲取計算的結果

9.概括的解釋下線程的幾種可用狀態

線程在執行過程中,可以處於下面幾種狀態:

  • 就緒(Runnable):線程準備運行,不一定立馬就能開始執行。
  • 運行中(Running):進程正在執行線程的代碼。
  • 等待中(Waiting):線程處於阻塞的狀態,等待外部的處理結束。
  • 睡眠中(Sleeping):線程被強制睡眠。
  • I/O阻塞(Blocked on I/O):等待I/O操作完成。
  • 同步阻塞(Blocked on Synchronization):等待獲取鎖。
  • 死亡(Dead):線程完成了執行    

10.同步方法和同步代碼塊的區別

在實際開發中,可能會出現一個方法只有2、3行代碼有多線程的問題,如果使用同步方法,那麼就會把方法中的所有代碼都放在同步方法裏面,這樣做不好的地方是,此方法同一時間只允許一個線程訪問該方法,其他線程無法訪問,這樣會嚴重影響代碼的執行效率

如果使用同步代碼塊,只將可能會出現多線程問題的代碼放在同步代碼塊裏面,那麼當一個線程訪問同步代碼塊裏面的代碼時,其他線程也可以訪問方法裏其他的代碼,這樣代碼執行效率會大大增加。所以,通常情況下,能使用同步代碼塊就儘量使用同步代碼塊

參考文章:

      同步方法和同步代碼塊的使用和區別

11.並行和併發有什麼區別?

並行:是兩個任務同時運行,系統擁有一個以上CPU,一個CPU執行一個進程,另一個CPU進行另外一個進程,兩個進程同時進行,互不搶佔資源,這種方式稱爲並行

併發:指兩個任務都請求運行,而處理器只能接受一個任務,就把這兩個任務安排輪流進行,由於時間間隔較短,使人感覺兩個任務都在運行

簡言之:

     並行是在同一時刻執行多個事件,併發是在同一時間段執行內執行多個事件

     併發編程可以充分的利用CPU,達到最高的處理性能

12.什麼是守護線程?

守護線程具有最低的優先級,用於爲系統中的其他對象和線程提供服務,比如GC線程,如果沒有其他用戶線程在運行,那麼就沒有可服務對象,也就沒有理由繼續下去

守護線程使用的情況較少,但並非沒有用,比如JVM的垃圾回收、內存管理等線程都是守護線程,還有在做數據庫應用時,使用的數據庫連接池,連接池本身也包含着很多後臺進程,監控連接個數,超時時間,狀態等

守護線程和用戶線程的唯一區別

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章