由於線程池是在提交任務時根據狀況執行拒絕策略的,而提交任務涉及兩個方法: execute 和 sumbit。在說拒絕策略以前,先談談這兩方法的區別。前端
先看看 submit 的源碼:能夠看到它最終仍是調用 execute 方法。與 execute 的區別就是:能夠接收線程池執行的返回值,而 execute () 不能接收返回值。java
public Future < ? > submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture < Void > ftask = newTaskFor(task, null); execute(ftask); return ftask; }
再看 execute 源碼,註釋寫得很清楚了,簡單說下,分爲三步:面試
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); // 當前工做的線程數小於核心線程數 if (workerCountOf(c) < corePoolSize) { // 建立新的線程執行此任務 if (addWorker(command, true)) return; c = ctl.get(); } // 檢查線程池是否處於運行狀態,若是是則把任務添加到隊列 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); // 再次檢查線程池是否處於運行狀態,防止在第一次校驗經過後線程池關閉 // 若是是非運行狀態,則將剛加入隊列的任務移除,並執行拒絕策略 if (!isRunning(recheck) && remove(command)) reject(command); // 若是線程池的線程數爲 0 時(當 corePoolSize 設置爲 0 時會發生) // 新建線程執行任務 else if (workerCountOf(recheck) == 0) addWorker(null, false); // 核心線程都在忙且隊列都已爆滿,嘗試新啓動一個線程執行失敗 } else if (!addWorker(command, false)) // 執行拒絕策略 reject(command); }
Java 給咱們提供了拒絕策略,建立線程池時就能夠指定拒絕策略,好比:算法
newThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue < > (), new ThreadPoolExecutor.AbortPolicy());
固然,你也能夠本身實現~數據庫
上面瞭解了拒絕策略的執行時機,再來看看 Java 給咱們提供的拒絕策略。分爲四種,關係以下:編程
逐個聊聊它們的特色:設計模式
本文從源碼分析了拒絕策略的執行時機並詳細介紹了 Java 提供的四種拒絕策略,相信你們看完會有所收穫。選用哪一種線程池是根據你本身的業務而定的,實踐出真知。微信
若是看到這裏,喜歡這篇文章的話,請幫點個好看。微信搜索一個優秀的廢人,關注後回覆電子書送你 1000+ 本編程電子書 ,不僅 Java 哦,詳情看下圖。回覆 1024送你一套完整的某課網 java 就業班視頻教程。數據結構