任務邊界:當圍繞「任務執行」來設計應用程序時,第一步就是要找出清晰的任務邊界。緩存
線程生命週期的開銷很是高:線程的建立於銷燬併發
資源消耗:活躍的線程會消耗系統資源,尤爲是內存。若是可運行的線程數量多於可用處理器的數量,那麼有些線程將閒置。因此,若是已經擁有足夠多的線程使CPU保持忙碌狀態,那麼建立再多的線程反而會下降性能框架
穩定性:在可建立線程的數量上存在必定限制,這個閒置值將隨平臺的不一樣而不一樣,而且受多個因素閒置。若是破壞了這些限制,那麼可能拋出OutOfMemoryError異常函數
應該對程序中建立的線程數量進行限制。
在Java中,執行任務的主要抽象不是Thread,而是Executor。
public interface Executor { void execute(Runnable command); }
Executor框架能支持多種不一樣類型的任務執行策略,它提供了一種標準的方法將任務的提交過程與執行過程解耦,並用Runnable來表示任務。Executor的實現還提供了對生命週期的支持,以及統計信息收集、應用程序管理機制和性能監視等機制。 Executor基於生產者----消費者模式,提交任務的操做至關於生產者,執行任務的線程至關於消費者。性能
JVM只有在全部(非守護)線程都終止後纔會退出,所以,若是Executor沒有正確關閉,那麼JVM將沒法退出。 Executor執行的任務有4個證實週期階段:建立、提交、開始和完成。已提交但還沒有開始的任務能夠取消,但對於已經開始執行的任務,只有當他們響應中斷時才能取消。 Executor擴展了ExecutorService接口,用於管理生命週期:線程
//Executor的生命週期有3中運行狀態:運行、關閉和已終止。 public interface ExecutorService extends Executor { /*shutdown執行平穩的關閉過程:再也不接受新任務,同時等待已提交的任務執行完----包括那些還未開始執行的任務*/ void shutdown(); /*shutdownNow將執行粗暴的關閉過程:它將嘗試取消全部運行中的任務,而且再也不啓動隊列中還沒有開始執行的任務*/ List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedExecutor; }
Executor的缺陷:設計
在執行策略中定義了任務執行的「What、Where、When、How」等方面。包括: 1. 在什麼(what)線程中執行 2. 任務按照什麼順序(FIFO、LIFO、優先級)執行 3. 有多少個(how many)任務能併發執行 4. 在隊列中有多少個(how many)任務等待執行 5. 若是系統因爲過載而須要拒絕一個任務,那麼應該選擇哪個(which)任務?另外如何(how)通知應用程序有任務被拒絕 6. 在執行一個任務以前或以後,應該進行哪些(what)動做code
線程池指管理一組同構工做線程的資源池。 能夠經過調用Executor中的一些靜態函數建立線程池:對象
newFixedThreadPool:建立一個固定長度的線程池,每當提交一個任務時就建立一個線程,直到建立的線程數量達到最大,此後線程的數量不會再變化。若是某個線程因爲發生未預期的Exception而結束,那麼線程會補充一個新的線程排序
newCachedThreadPool:建立一個可緩存的線程池,若是線程池的規模超過了處理需求,那麼將回收空閒的線程,而當需求增長時,則能夠添加新的線程,線程池的規模不存在人任何限制
newSingleThreadExecutor:單線程的Executor,它建立單個工做者線程來執行任務,若是這個線程異常結束,會建立一個新的線程來代替,其能確保依照任務在隊列中的順序串行序執行
new ScheduledThreadPool:建立一個固定長度的線程池,並且以延時或定時的方式來執行順序
「在線程池中執行任務」要比「爲每一個任務分配一個線程」優點更多。
Timer類負責管理延遲任務以及週期任務,可是Timer類存在一些缺陷,應該考慮使用ScheduledThreadPool類代替它。 Timer類的缺陷
Timer在執行全部定時任務時只會建立一個線程,若是某個任務的延時時間過長,那麼將破壞其餘TimerTask的定時精確性。
若是TimerTask拋出了一個未受檢查的異常,因爲Timer線程並不捕獲異常,所以Timer將終止線程的執行。
若是要構建本身的調度服務,那麼可使用DelayQueue,它實現了BlockingQueue,併爲ScheduledThreadPoolExecutor提供調度功能。DelayQueue管理着一組Delayed對象,每一個Delayed對象都有一個相應的延遲時間:在DelayQueue中,只有某個元素逾期後,才能從DelayQueue中執行take操做,從DelayQueue中返回的對象將根據他們的延遲時間進行排序。
Callable提供了一種相比Runnable更好的抽象:call,call()有返回值(要用Callable表示無返回值的任務,使用Callable<void>),而且容許拋出異常。 Future表示一個任務的生命週期,並提供了相應的方法來判斷是否已經完成或取消,以及獲取任務的結果和取消任務等。Future意味着任務的生命週期只能前進,不能後退。 若是任務拋出了異常,那麼get將異常封裝爲ExecutorException並從新拋出,而且能夠經過getCause來得到被封裝的初始異常,若是任務被取消,那麼get將拋出 CancellationException
public interface Callable<V> { V call() throws Exception; } public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException,ExecutionException, CancellationException; V get(long timeOut,TimeUnit unit) throws InterruptedException,ExecutionException, CancellationException,TimeoutException; }
只有當大量相互獨立且同構的任務能夠併發處理時,才能體現出將程序的工做負載分配到多個任務中帶來的性能提高。