1. 程式人生 > 其它 >java面經-執行緒池

java面經-執行緒池

一、建立執行緒的三種方式

1、通過繼承Thread類繼承

  

2、通過Runnable介面,重寫run方法建立

3、通過Callable介面,實現call方法的建立

4、使用執行緒池的方式建立

 

 

二、為什麼要用執行緒池

執行緒池提供了一種限制和管理資源(包括執行一個任務)的方式,每一個執行緒池都維護了一些基本的統計資訊,例如已完成的任務數量。

執行緒池的優點:

1、降低資源消耗。通過重複利用已建立的執行緒降低執行緒建立和銷燬造成消耗

2、提高響應速度,當任務到大時,任務可以不需要等到執行緒建立就能夠立即執行。

3、提高執行緒的可管理性。執行緒是稀缺資源,如果無限制建立,不僅會消耗系統資源,還會降低系統的穩定性,使用執行緒可以統一分配和調優監控。

 

三、實現Runnable介面和Callable介面的區別

Runnable自1.0以來一直存在,但callable僅在jdk1.5引入,目的是為了處理runnable不支援的用例。

runnbale介面不會返回結果或丟擲檢查異常,但是callable可以。

所以如果任務不需要返回結果和丟擲異常,推薦使用runnable介面,這樣程式碼會更簡潔。

 

四、執行緒池實現的兩種方法(1、ThreadPoolExecutor構造方法,2、使用Executor框架的工具類Executors來實現)

第一種ThreadPoolExecutor 三個重要引數:

1、corePoolSize:核心執行緒數定義了最小可以同時執行的執行緒數

2、maximumPoolSize:當前佇列存放的任務到大佇列容量的時候,當前程式可以同時執行的執行緒數量最大的執行緒數

3、workQueue:當前任務佇列。當前任務來了判斷是否還有執行緒能夠處理,如果不能就進入任務佇列

四個其他引數:

4、keepAlive:當前執行緒數量大於corePoolSize的時候,如果這個時候沒有任務提交,核心執行緒外的執行緒不會立即銷燬,而是等待,時間超過了就會被銷燬。

5、unit:引數 的時間單位

6、threadFactory:executor建立新執行緒的時候會用到

7、handler:飽和拒絕策略。

 

飽和策略定義:

如果當前同時執行的執行緒數量達到最大執行緒數量,並且佇列已被放滿的時候,ThreadPoolTaskExecutor定義了一些策略:

1、ThreadPoolExecutor.AbortPolicy:丟擲RejectedExecutionException來拒絕新任務的處理

2、ThreadPoolExecutor.CallerRunsPolicy:呼叫執行自己的執行緒執行任務,也就是直接呼叫execute (讓呼叫者自己去執行任務,非執行緒池中的執行緒執行)。

方法的執行緒中執行run被拒絕的任務,如果執行程式已關閉,則丟棄該任務。因此這種策略降低了新任務的提交速度

影響程式的整體效能。如果程式可以承受這種延遲,可以選擇該策略。

3、ThreadPoolExecutor.DiscardPolicy:不處理新任務,直接丟棄

4、ThreadPoolExecutor.DiscardOldestPolicy:此策略將丟棄最早未處理的請求。

 

阿里巴巴推薦中:不允許使用Executors建立執行緒,而是通過ThreadPoolExecutor的方式,這樣處理方式規避資源消耗風險,明確執行緒池的執行規則。

弊端主要還是回可能造成OOM

FixedThreadPool和SingleThreadExecutor:允許請求佇列的長度為Integer.MAX_VALUE,可能堆積大量的請求,導致OOM

CacheThreadPool和ScheduledThreadPool:允許建立執行緒數量為Integer.MAX_VALUE,可能會建立大量執行緒,導致OOM

 

執行緒池原理分析: