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()); } }
看下結果