技術問答集錦(12)併發程式設計-任務執行

猿碼道發表於2018-03-23

1 序列執行的缺點?

程式碼序列執行,同步等待時間較長,CPU利用率低,造成糟糕的響應性和吞吐量;

2 每一個任務建立一個執行緒的不足?

  1. 執行緒生命週期開銷非常高;
  2. 資源消耗:當可執行執行緒數多於可用處理器的數量,會有執行緒閒置佔用記憶體,且大量執行緒競爭CPU導致效能開銷;
  3. 穩定性:不同平臺可建立執行緒的數量有限制;

3 為什麼要用執行緒池,如何合理的設定執行緒數量?

  1. 限制系統中使用執行緒的數量以及更好的使用執行緒;
  2. 減少執行緒建立和銷燬的次數,使執行緒可以多次複用;
  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方法呼叫後,任務會何時執行?

ThreadPoolExecutor.execute() => addWorker()

7 如果自己設計任務執行框架,要考慮哪些方面?

  1. 在什麼(What)執行緒中執行任務?
  2. 任務按照什麼(What)順序執行(優先順序)?
  3. 有多少個(How Many)任務能併發執行?
  4. 在佇列中有多少個(How Many)任務在等待執行?
  5. 系統該怎麼(How)拒絕任務?
  6. 在任務執行前後,應該進行哪些(What)動作?

8 Timer執行任務會有什麼缺點?

  1. Timer執行定時任務只會建立一個執行緒。
  2. Timer是基於絕對時間的排程機制,對系統時間敏感。
  3. Timer存線上程洩露問題(Timer不捕獲異常,當丟擲一個未檢查異常時執行緒將終止)。

相關文章