1 序列執行的缺點?
程式碼序列執行,同步等待時間較長,CPU利用率低,造成糟糕的響應性和吞吐量;
2 每一個任務建立一個執行緒的不足?
- 執行緒生命週期開銷非常高;
- 資源消耗:當可執行執行緒數多於可用處理器的數量,會有執行緒閒置佔用記憶體,且大量執行緒競爭CPU導致效能開銷;
- 穩定性:不同平臺可建立執行緒的數量有限制;
3 為什麼要用執行緒池,如何合理的設定執行緒數量?
- 限制系統中使用執行緒的數量以及更好的使用執行緒;
- 減少執行緒建立和銷燬的次數,使執行緒可以多次複用;
- 根據系統情況,調整執行緒的數量。防止建立過多的執行緒,消耗過多的記憶體;
確認APP型別(N為CPU總合數):(1)CPU密集型:執行緒池大小設定為N+1;(2)IO密集型:執行緒池大小設定為2N+1;
一個估算公式:最佳執行緒數目 = (執行緒等待時間與執行緒CPU時間之比 + 1)* CPU數目;
執行緒等待時間所佔比例越高,需要越多執行緒。執行緒CPU時間所佔比例越高,需要越少執行緒。
一個系統最快的部分是CPU,所以決定一個系統吞吐量上限的是CPU。增強CPU處理能力,可以提高系統吞吐量上限。但根據短板效應,真實的系統吞吐量並不能單純根據CPU來計算。那要提高系統吞吐量,就需要從“系統短板”(比如網路延遲、IO)著手:
(1)儘量提高短板操作的並行化比率,比如多執行緒下載技術;
(2)增強短板能力,比如用NIO替代IO;
第(1)條聯絡到Amdahl定律,這條定律定義了序列系統並行化後的加速比計算公式:
加速比=優化前系統耗時 / 優化後系統耗時
加速比越大,表明系統並行化的優化效果越好。Addahl定律還給出了系統並行度、CPU數目和加速比的關係,加速比為Speedup,系統序列化比率(指序列執行程式碼所佔比率)為F,CPU數目為N:
Speedup <= 1 / (F + (1-F)/N)
當N足夠大時,序列化比率F越小,加速比Speedup越大。其他詳細內容,請參考《如何合理地估算執行緒池大小?》
4 如何計算JVM可建立執行緒的最大數量?
首先要說明一點,Java執行緒的實現是基於底層系統的執行緒機制來實現的,程式中開的執行緒並不全部取決於JVM虛擬機器棧,而是取決於CPU,作業系統,其他程式,Java的版本。JVM的執行緒與計算機本身效能相關。
在不考慮系統本身限制的情況下,主要跟JVM一下幾點有關:
-Xms 初始堆大小 (在實際生產中,一般把-Xms和-Xmx設定成一樣的。)
-Xmx 最大堆大小
-Xss 每個執行緒棧大小
結論1:當給JVM的堆記憶體分配的越大,系統可建立的執行緒數量就越少;
結論2:當-Xss的的值越小,可生成的執行緒數量就越多,JDK5以下預設好像是256K,以上預設為1M;
總結:執行緒最大數量由JVM的堆(-Xmx,-Xms)大小、Thread的棧(-Xss)記憶體大小、系統最大可建立的執行緒數的限制引數三個方面影響。不考慮系統限制,可以通過這個公式估算:
執行緒數量 = (機器本身可用記憶體 - JVM分配的堆記憶體) / Xss的值。
5 Runnable是介面還是類?為什麼Runnable介面可以new?介面中方法、變數預設修飾符?
Runnable是介面,因為new Runnable介面產生的是一個匿名內部類,介面中的變數的修飾符預設為public static final;介面中的方法的修飾符預設為public abstract;
介面是一種高度抽象的模版,介面中的成員變數是模版的一部分,其介面的實現類必須共有這些成員變數,所以成員變數的修飾符預設為public、static、final。static使得實現這個介面的類,可以直接使用這個變數。如果是非靜態變數,那麼介面的多個實現類可能出現變數名重名的現象。final表示被修飾的變數為常數,不可以修改。一個既是static又是final的欄位表示只佔據一段不能改變的儲存空間。如果是非final變數,那麼介面的實現類可以修改變數的值,這與抽象類沒有區別了。由於介面起到標準化和規範化的作用,所以其成員變數預設修飾符為static、final。
6 execute方法呼叫後,任務會何時執行?
7 如果自己設計任務執行框架,要考慮哪些方面?
- 在什麼(What)執行緒中執行任務?
- 任務按照什麼(What)順序執行(優先順序)?
- 有多少個(How Many)任務能併發執行?
- 在佇列中有多少個(How Many)任務在等待執行?
- 系統該怎麼(How)拒絕任務?
- 在任務執行前後,應該進行哪些(What)動作?
8 Timer執行任務會有什麼缺點?
- Timer執行定時任務只會建立一個執行緒。
- Timer是基於絕對時間的排程機制,對系統時間敏感。
- Timer存線上程洩露問題(Timer不捕獲異常,當丟擲一個未檢查異常時執行緒將終止)。