java線程池(2)---常見線程池

線程池的創建和使用
生成線程池採用了工具類Executors的靜態方法,一下是幾種常見的線程池。

SingleThreadExecutor:單個後臺線程(其緩衝隊列是無界的)

public static ExecutorService newSingleThreadExecutor(){
    return new FinalizableDelegatedExecutorService(
    new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkdBlockingQueue<Runnable>()));
}

簡介:
創建一個單線程的線程池。這個線程池只用一個核心線程在工作,也就是相當於單線程串行執行多個任務。如果這個唯一的線程因爲異常結束,那麼會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序來執行。

FixedThreadPool:只有核心線程的線程池,大小固定(其緩衝隊列是無界的)

public static ExecutorService newFixedThreadPool(int nThreads){
    return new ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}

簡介:
創建固定大小的線程池。每次提交一個任務就創建一個線程,知道線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因爲執行異常而結束,那麼線程池會補充一個新的線程。

CachedThreadPool:無界線程池,可以進行自動線程回收。

public static ExecutorService newCachedThreadPool(){
    return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}

簡介:
如果線程池的大小超過了處理任務所需要的線程,那麼就會回收部分空閒(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴於操作系統(或者說JVM)能夠創建的最大線程大小。
SynchronousQueue是一個緩衝區爲1的阻塞隊列。

ScheduledThreadPool:核心線程池固定,大小無限的線程池。此線程池支持定時以及週期性執行任務的需求。

public static ExecutorService newScheduledThreadPool(int corePoolSize){
    return new ScheduledThreadPool(corePoolSize,Integer.MAX_VALUE,DEFAULT_KEEPALIVE_MILLIS,MILLISECONDS,new DelayedWorkedQueue());
}

簡介:
創建一個週期性執行任務的線程池。如果閒置,非核心線程池會在DEFAULT_KEEPALIVEMILLIS時間內回收。

線程池最常用的提交任務的方法有兩種:
execute:

ExecutorService.execute(Runnable runnable);

submit:

FutureTask task = ExecutorService.submit(Runnable runnable);
FutureTask<T> task = ExecutorService.submit(Runnable runnable,T Result);
FutureTask<T> task = ExecutorService.sumbit(Callable<T> callable);

submit(Callable callable)的實現,submit(Runnable runnable)同理。

public <T> Future<T> submit(Callable<T> task){
    if(task==null)
        throw new NullPointerException();
        FutureTask<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
}

可以看出submit開啓的是有返回結果的任務,會返回一個FutureTask對象,這樣就能通過get()方法得到結果。submit最終調用的也是executor(Runnable runnable),submit只是將Callable對象或Runnable封裝成一個FutureTask對象,因爲FutureTask是個Runnable,所以在executor中執行。

今天的總結就到這裏!!!
感謝愛技術的你們的陪伴!!!
我以後還會繼續更新知識!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章