代碼串行執行,同步等待時間較長,CPU利用率低,形成糟糕的響應性和吞吐量;網絡
- 線程生命週期開銷很是高;
- 資源消耗:當可運行線程數多於可用處理器的數量,會有線程閒置佔用內存,且大量線程競爭CPU致使性能開銷;
- 穩定性:不一樣平臺可建立線程的數量有限制;
- 限制系統中使用線程的數量以及更好的使用線程;
- 減小線程建立和銷燬的次數,使線程能夠屢次複用;
- 根據系統狀況,調整線程的數量。防止建立過多的線程,消耗過多的內存;
確認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:code
Speedup <= 1 / (F + (1-F)/N)
當N足夠大時,串行化比率F越小,加速比Speedup越大。其餘詳細內容,請參考《如何合理地估算線程池大小?》
首先要說明一點,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的值。
Runnable是接口,由於new Runnable接口產生的是一個匿名內部類,接口中的變量的修飾符默認爲public static final;接口中的方法的修飾符默認爲public abstract;
接口是一種高度抽象的模版,接口中的成員變量是模版的一部分,其接口的實現類必須共有這些成員變量,因此成員變量的修飾符默認爲public、static、final。static使得實現這個接口的類,能夠直接使用這個變量。若是是非靜態變量,那麼接口的多個實現類可能出現變量名重名的現象。final表示被修飾的變量爲常數,不能夠修改。一個既是static又是final的字段表示只佔據一段不能改變的存儲空間。若是是非final變量,那麼接口的實現類能夠修改變量的值,這與抽象類沒有區別了。因爲接口起到標準化和規範化的做用,因此其成員變量默認修飾符爲static、final。
- 在什麼(What)線程中執行任務?
- 任務按照什麼(What)順序執行(優先級)?
- 有多少個(How Many)任務能併發執行?
- 在隊列中有多少個(How Many)任務在等待執行?
- 系統該怎麼(How)拒絕任務?
- 在任務執行先後,應該進行哪些(What)動做?
- Timer執行定時任務只會建立一個線程。
- Timer是基於絕對時間的調度機制,對系統時間敏感。
- Timer存在線程泄露問題(Timer不捕獲異常,當拋出一個未檢查異常時線程將終止)。