动态

详情 返回 返回

某訊面試中常見的Java多線程面試題 - 动态 详情

這是我花費時間為大家整理的騰訊面試中常問的多線程面試題,看看你掌握多少?

1.什麼是進程?什麼是線程?
2.説説線程的生命週期和狀態?
3.什麼是上下文切換?
4.創建線程創建的方式都有哪些?
5.synchronized 關鍵字的作用
6.線程池的核心構造參數有哪些?

1. 什麼是進程?什麼是線程?

什麼是進程?

進程是程序的一次執行過程,是系統運行程序的基本單位,因此進程是動態的。
系統運行一個程序即是一個進程從創建,運行到消亡的過程。在 Java 中,當我們啓動 main 函數時其實就是啓動了一個 JVM 的進程,而 main 函數所在的線程就是這個進程中的一個線程,也稱主線程。

下面是進程的特點,幫助大家更好地理解進程

獨立性 :進程之間是獨立的,互不干擾。一個進程的崩潰不會影響其他進程。
資源豐富 :每個進程擁有獨立的資源,包括內存、文件句柄等。
開銷大 :創建和銷燬進程的開銷較大,進程間通信(IPC)也相對複雜。
上下文切換 :進程的上下文切換開銷較大,因為需要切換內存空間和資源。
使用場景 :適用於需要強隔離和獨立資源的場景,如獨立的服務、應用程序等。

什麼是線程?

線程與進程相似,但線程是一個比進程更小的執行單位。一個進程在其執行的過程中可以產生多個線程。
與進程不同的是同類的多個線程共享進程的堆和方法區資源,但每個線程有自己的程序計數器、虛擬機棧和本地方法棧,所以系統在產生一個線程,或是在各個線程之間做切換工作時,負擔要比進程小得多,也正因為如此,線程也被稱為輕量級進程。

下面是線程的特點,幫助大家更好地理解線程

共享資源 :同一進程內的線程共享內存和資源,通信方便。
輕量級 :線程的創建和銷燬開銷較小,上下文切換較快。
併發執行 :多線程可以併發執行,提高程序的響應速度和資源利用率。
同步問題 :由於共享資源,線程間需要同步機制(如鎖)來避免資源競爭和數據不一致。
使用場景 :適用於需要併發執行的任務,如多任務處理、並行計算等。

2. 説説線程的生命週期和狀態?

Java 線程在運行的生命週期中的指定時刻只可能處於下面 6 種不同狀態的其中一個狀態。關於這個知識點,大家記住這 6 個狀態,理解每個狀態就行

NEW : 初始狀態,線程被創建出來但沒有被調用 start() 。
RUNNABLE : 運行狀態,線程被調用了 start()等待運行的狀態。
注意:在 Java 中,Runnable 狀態包括了運行狀態(Running),即線程可以運行,也可能正在運行。
BLOCKED :阻塞狀態,需要等待鎖釋放。
WAITING :等待狀態,表示該線程需要等待其他線程做出一些特定動作(通知或中斷)。
TIME_WAITING :超時等待狀態,可以在指定的時間後自行返回而不是像 WAITING 那樣一直等待。
TERMINATED :終止狀態,表示該線程已經運行完畢。線程在生命週期中並不是固定處於某一個狀態而是隨着代碼的執行在不同狀態之間切換。

3. 什麼是上下文切換?

多線程編程中一般線程的個數都大於 CPU 核心的個數,而一個 CPU 核心在任意時刻只能被一個線程使用,為了讓這些線程都能得到有效執行,CPU 採取的策略是為每個線程分配時間片並輪轉的形式。
當一個線程的時間片用完的時候就會重新處於就緒狀態讓給其他線程使用,這個過程就屬於一次上下文切換


概括來説就是:當前任務在執行完 CPU 時間片切換到另一個任務之前會先保存自己的狀態,以便下次再切換回這個任務時,可以再加載這個任務的狀態。任務從保存到再加載的過程就是一次上下文切換。


上下文切換通常是計算密集型的。也就是説,它需要相當可觀的處理器時間,在每秒幾十上百次的切換中,每次切換都需要納秒量級的時間。所以,上下文切換對系統來説意味着消耗大量的 CPU 時間,事實上,可能是操作系統中時間消耗最大的操作。

4. 創建線程創建的方式都有哪些?

繼承 Thread 類
實現 Runnable 接口
使用 Callable 和 Future 創建線程
基本創建線程的方式大體就是這三種,當然也可以使用線程池創建線程。

下面是演示一下具體怎麼創建線程

  1. 繼承 Thread 類,重寫 run 方法:
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " run()方法正在執行...");
    }
}
  1. 實現 Runnable 接口,實現 run 方法:
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " run()方法執行中...");
    }
}
  1. 實現 Callable 接口,實現 call 方法。通過 FutureTask 創建一個線程,獲取到線程執行的返回值:
public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() {
        System.out.println(Thread.currentThread().getName() + " call()方法執行 中...");
        return 1;
    }
}

5. synchronized 關鍵字的作用

synchronized 它可以把任意一個非 NULL 的對象當作鎖。他屬於獨佔式的悲觀鎖,同時屬於可重入鎖。

synchronized 關鍵字解決的是多個線程之間訪問資源的同步性,synchronized 關鍵字可以保證被它修飾的方法或者代碼塊在任意時刻只能有一個線程執行。

這是 synchronized 的三種使用方式:

修飾實例方法 :作用於當前對象實例加鎖,進入同步代碼前要獲得當前對象實例的鎖
synchronized void method() {
    //業務代碼
}
修飾靜態方法 :也就是給當前類加鎖,會作用於類的所有對象實例,因為靜態成員不屬於任何一個實例對象,是類成員。
所以如果一個線程 A 調用一個實例對象的非靜態 synchronized 方法,而線程 B 需要調用這個實例對象所屬類的靜態 synchronized 方法,是允許的,不會發生互斥現象,因為訪問靜態 synchronized 方法佔用的鎖是當前類的鎖,而訪問非靜態 synchronized 方法佔用的鎖是當前實例對象鎖。
synchronized static void method() {
    //業務代碼
}
修飾代碼塊 : 指定加鎖對象,對給定對象加鎖,進入同步代碼庫前要獲得給定對象的鎖。
synchronized(this) {
    //業務代碼
}

6. 線程池的核心構造參數有哪些?

線程池一共 7 個核心構造參數,大家牢記即可。

1.corePoolSize(核心線程數)

線程池中始終保持運行的最小線程數,即使這些線程處於空閒狀態也不會被銷燬。
當提交一個新任務時,如果當前運行的線程數少於 corePoolSize,即使有空閒線程,也會創建一個新線程來處理任務。

2.maximumPoolSize(最大線程數)

線程池允許創建的最大線程數。當任務隊列已滿且當前運行的線程數小於 maximumPoolSize 時,會創建新線程來執行任務。

3.keepAliveTime(線程空閒時間)

當線程池中的線程數超過 corePoolSize 時,多餘的空閒線程在等待新任務的最大時間。超過這個時間後,這些空閒線程將被終止。

4.unit(時間單位

keepAliveTime 參數的時間單位。可以是 TimeUnit 枚舉中的任意值,如TimeUnit.SECONDS、TimeUnit.MILLISECONDS等。

5.workQueue(任務隊列)

用於保存等待執行的任務的隊列。

常用的隊列實現包括:

  • LinkedBlockingQueue:一個基於鏈表的無界隊列。
  • ArrayBlockingQueue:一個基於數組的有界隊列。
  • SynchronousQueue:一個不存儲元素的隊列,每個插入操作必須等待一個對應的移除操作。
  • PriorityBlockingQueue:一個支持優先級排序的無界隊列。

6.threadFactory(線程工廠)

用於創建新線程的工廠。可以通過自定義線程工廠來設置線程的名稱、優先級等屬性。默認實現是Executors.defaultThreadFactory()

7.handler(拒絕策略)

當任務隊列已滿且線程數量達到最大線程數時,新的任務會被拒絕執行。拒絕策略定義了這種情況下的處理方式。

常用的拒絕策略包括:

  • AbortPolicy:拋出 RejectedExecutionException,默認策略。
  • CallerRunsPolicy:由調用線程執行任務。
  • DiscardPolicy:丟棄任務,不拋出異常。
  • DiscardOldestPolicy:丟棄隊列中最舊的任務,然後重新嘗試提交新任務。

就業陪跑訓練營學員投稿

歡迎關注 ❤

我們搞了一個免費的面試真題共享羣,互通有無,一起刷題進步。

沒準能讓你能刷到自己意向公司的最新面試題呢。

感興趣的朋友們可以加我微信:wangzhongyang1993,備註:思否面試羣。

user avatar zhidechaomian_detxs7 头像 binghe001 头像 huidadebianpao 头像 nianqingyouweidenangua 头像 changqingdezi 头像 gouguoyin 头像 huobaodejianpan 头像 junxiudedoujiang 头像 nizi_60e514d097c9a 头像 kason_5c6fb9100a56b 头像 hunterxiong 头像 yifu 头像
点赞 12 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.