更新時間:2022-12-21 15:36:22 來源:動力節點 瀏覽1242次
1、什么是線程和進程?
進程:在操作系統中能夠獨立運行,并且作為資源分配的基本單位。它表示運行中的程序。系統運行一個程序就是一個進程從創建、運行到消亡的過程。
線程:是一個比進程更小的執行單位,能夠完成進程中的一個功能,也被稱為輕量級進程。一個進程在其執行的過程中可以產生多個線程。
【注】線程與進程不同的是:同類的多個線程共享進程的堆和方法區資源,但每個線程有自己的程序計數器、虛擬機棧和本地方法棧,所以系統在產生一個線程,或是在各個線程之間作切換工作時,負擔要比進程小得多。
為什么程序計數器、虛擬機棧和本地方法棧是線程私有的呢?為什么堆和方法區是線程共享的呢?
程序計數器主要有下面兩個作用:
字節碼解釋器通過改變程序計數器來依次讀取指令,從而實現代碼的流程控制,如:順序執行、選擇、循環、異常處理。
在多線程的情況下,程序計數器用于記錄當前線程執行的位置,從而當線程被切換回來的時候能夠知道該線程上次運行到哪兒了。
(需要注意的是,如果執行的是 native 方法,那么程序計數器記錄的是 undefined 地址,只有執行的是 Java 代碼時程序計數器記錄的才是下一條指令的地址。)
所以,程序計數器私有主要是為了線程切換后能恢復到正確的執行位置。
虛擬機棧: 每個 Java 方法在執行的同時會創建一個棧幀用于存儲局部變量表、操作數棧、常量池引用等信息。從方法調用直至執行完成的過程,就對應著一個棧幀在 Java 虛擬機棧中入棧和出棧的過程。
本地方法棧: 和虛擬機棧所發揮的作用非常相似,區別是: 虛擬機棧為虛擬機執行 Java 方法 (也就是字節碼)服務,而本地方法棧則為虛擬機使用到的 Native 方法服務。 在 HotSpot 虛擬機中和 Java 虛擬機棧合二為一。
所以,為了保證線程中的局部變量不被別的線程訪問到,虛擬機棧和本地方法棧是線程私有的。
堆和方法區是所有線程共享的資源,其中:
堆是進程中最大的一塊內存,主要用于存放新創建的對象 (所有對象都在這里分配內存)。
方法區主要用于存放已被加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。
2、什么是上下文切換?
即使單核處理器也支持多線程執行代碼,CPU通過給每個線程分配CPU時間片來實現這個機制。時間片是CPU分配給各個線程的時間,因為時間片非常短,所以CPU通過不停地切換線程執行,讓我們感覺多個線程是同時執行的。(時間片一般是幾十毫秒)
CPU通過時間片分配算法來循環執行任務,當前任務執行一個時間片后會切換到下一個任務。但是,在切換前會保存上一個任務的狀態,以便下次切換回這個任務時,可以再加載這個任務的狀態。所以任務從保存到加載的過程就是一次上下文切換。上下文切換會影響多線程的執行速度。
3、并發與并行?
并發指的是多個任務交替進行,并行則是指真正意義上的“同時進行”。
實際上,如果系統內只有一個CPU,使用多線程時,在真實系統環境下不能并行,只能通過切換時間片的方式交替進行,從而并發執行任務。真正的并行只能出現在擁有多個CPU的系統中。
4、線程的生命周期和狀態?(重要!)
Java 線程在運行的生命周期中的指定時刻只可能處于下面 6 種不同狀態的其中一個狀態:
初始狀態、運行狀態、阻塞狀態、等待狀態、超時等待狀態、終止狀態
線程在生命周期中并不是固定處于某一個狀態而是隨著代碼的執行在不同狀態之間切換:
5、什么是線程死鎖?如何避免死鎖?
多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。由于線程被無限期地阻塞,因此程序不可能正常終止。
假如線程 A 持有資源 2,線程 B 持有資源 1,他們同時都想申請對方的資源,所以這兩個線程就會互相等待而進入死鎖狀態。
避免死鎖的幾個常見方法:
以上就是“大廠級別的多線程面試題”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節點Java官網。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習