常見執行緒池 newFixedThreadPool 的簡單使用
阿新 • • 發佈:2020-11-20
package com.aaa.threaddemo; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit; /* *一 四種常見的執行緒池是啥? * newFixedThreadPool * 1.建立一個可重用固定執行緒數的執行緒池, 2.使用共享的無界佇列方式來執行這些執行緒。 * * newCachedThreadPool * 1.可根據需要建立新執行緒的執行緒池 2.舊的執行緒可用時將重用他們 3.對短期非同步的程式 可提高程式效能 * * newSingleThreadExecutor * 1.返回一個執行緒池,只有一個執行緒 2.可以在舊的執行緒掛掉之後,重新啟動一個新的執行緒來替代它。 達到起死回生的效果。 * * newScheduledThreadPool * 給定一個延遲後,可以執行命令或者定期執行。 * java中執行緒池的頂級介面是Executor 嚴格而言,正在的執行緒池是ExecutorService * *二 阻塞佇列 LinkedBlockingQueue 使用注意事項? * *三 執行緒池提交任務的方式? * *四 shutdown 的使用方式? * *五 執行緒池中的常用引數設定?*/ /* 二 newFixedThreadPool * 1.建立一個固定大小的執行緒池 * 2.提交一個任務,就建立一個執行緒,直到執行緒池的最大容量。 * 3.執行緒池的大小達到最大值,就保持不變。 * 4.有執行異常而結束的執行緒,執行緒池會補充一個新的執行緒。 * 5.使用完畢,必須手動關閉執行緒池,否則會一直存在記憶體中 * * 看一下newFiexdThreadPool()的內心世界 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());*/ public class ThreaPoolUser { public static void main(String[] args) { ExecutorService fixedPool = Executors.newFixedThreadPool(2); //建立一個可重用,固定執行緒數的執行緒池 容量為 2 /* 執行緒池的容量是2,我這裡放入了3個執行緒,執行緒池會如何處理? 可以看到這裡有個沒有指定容量的佇列 linkedBlockingQueue,此時的佇列就是一個無邊界的佇列。 可以不斷的在佇列中新增任務 多放一個問題不大,300000個呢? 任務過多,就會導致記憶體溢位。 【注意!】 linkedBlockingQueue 本身是一個用連結串列結實現的有界阻塞佇列,容量是可以設定的。 較好的使用方式 五 ExecutorService executorService = new ThreadPoolExecutor( 10, //核心執行緒數 13, //執行緒池最大容量 60L, //非核心執行緒的生存時間 TimeUnit.SECONDS, //生存的時間單位 new ArrayBlockingQueue(10)); //設定佇列中的容量 */ FiexdDemo fiexdDemo = new FiexdDemo(); FiexdDemo fiexdDemo2 = new FiexdDemo(); FiexdDemo fiexdDemo3 = new FiexdDemo(); /* 三 執行緒池提交任務的方式有兩種 * 1.execute * 提交的是runnable型別的任務,下文的執行緒是繼承了thread,thread又是runnable的實現類。 * 提交是沒有返回值的 * 遇到異常直接丟擲 * * 2.submit * runnable 和 callable 都可提交 * 返回一個future型別的物件 * 將異常儲存,呼叫future get方法 才會丟擲異常 */ fixedPool.execute(fiexdDemo); fixedPool.execute(fiexdDemo2); fixedPool.execute(fiexdDemo3); /* 四 shutdown() * 1.把執行緒池的狀態設定為 shutdown,但是並不會馬上停止 * 2.停止接受外部的submit 任務 * 3.執行緒池正在執行的任務,佇列中等待的任務,會執行完 * 4.完成後,才是真正的停止 */ fixedPool.shutdown(); //手動關閉執行緒池 } } /* * 上面已經建立好了一個固定的執行緒池,這邊建立一個多執行緒。 * 把執行緒放進 執行緒池中就完事了。 */ class FiexdDemo extends Thread{ @Override public void run() { System.out.println("我是一個執行緒"); System.out.println("[currentThread = ]" + Thread.currentThread().getName()); } }
看下結果