在Java中,線程池的概念是Executor這個接口,具體實現爲ThreadPoolExecutor類,學習Java中的線程池,就能夠直接學習他了,對線程池的配置,就是對ThreadPoolExecutor構造函數的參數的配置。java
//五個參數的構造函數 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) //六個參數的構造函數-1 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) //六個參數的構造函數-2 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) //七個參數的構造函數 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
線程池新建線程的時候,若是當前線程總數小於corePoolSize,則新建的是核心線程,若是超過corePoolSize,則新建的是非核心線程 核心線程默認狀況下會一直存活在線程池中,即便這個核心線程啥也不幹(閒置狀態)。 若是指定ThreadPoolExecutor的allowCoreThreadTimeOut這個屬性爲true,那麼核心線程若是不幹活(閒置狀態)的話,超過必定時間(時長下面參數決定),就會被銷燬掉 很好理解吧,正常狀況下你不幹活我也養你,由於我總有用到你的時候,但有時候特殊狀況(好比我本身都養不起了),那你不幹活我就要把你幹掉了
int maximumPoolSize 該線程池中線程總數最大值函數
long keepAliveTime TimeUnit unit 該線程池中非核心線程閒置超時時長,一個非核心線程,若是不幹活(閒置狀態)的時長超過這個參數所設定的時長,就會被銷燬掉學習
BlockingQueue<Runnable> workQueue 見 這裏.net
ThreadFactory threadFactory 當須要建立一個新的線程時,會調用該方法。線程
RejectedExecutionHandler handler 這裏想對拒絕策略,在使用線程池而且使用有界隊列的時候,若是隊列滿了,任務添加到線程池的時候就會有問題,針對這些問題java線程池提供瞭如下幾種策略:code
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { //不作任何處理,直接拋出異常 throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { //移除隊頭元素 e.getQueue().poll(); //再嘗試入隊 e.execute(r); } }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { //直接執行run方法 r.run(); } }
PS: 不少文章裏並不關注拒絕策略,可是實際上,在開發過程當中咱們須要想象,若是線程被拒絕咱們應該怎麼處理。blog
線程池最基礎的類是Executor 是一個接口,只定義了一個execute,方法,表示運行一個Runnable。繼承
public interface Executor { void execute(Runnable command); }
而後是 ExecutorService 它也是一個接口,繼承了 Executor,在此基礎上主要提供了shutdown和submit能力。shutdown用於控制線程池中止,submit相似於execute,可是提供了Future支持(帶返回值)。接口
而後就是虛類 AbstractExecutorService 繼承了 ExecutorService 實現一些默認方法。隊列
再上層就是ThreadPoolExecutor 實現了 AbstractExecutorService。
Executors類中提供了一些默認特性的線程池,再加上自定義 ThreadPoolExecutor 基本上就夠用了。
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
繼承自 ThreadPoolExecutor,增長了定時功能。若是想實現定時運行就考慮一下這個東西。
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
使用的DelayedWorkQueue 隊列內元素必須實現Delayed接口,這就意味着你傳進去的任務必須先實現Delayed接口。這個隊列接收到任務時,首先先入隊,只有達到了指定的延時時間,纔會執行任務
https://blog.csdn.net/jgteng/article/details/54411423 https://blog.csdn.net/z69183787/article/details/80520659