咱們以前使用線程的時候都是使用new Thread來進行線程的建立,可是這樣會有一些問題。如:java
相比new Thread,Java提供的四種線程池的好處在於:緩存
java.util.concurrent.Executor 負責線程的使用和調度的根接口 |--ExecutorService 子接口: 線程池的主要接口 |--ThreadPoolExecutor 線程池的實現類 |--ScheduledExceutorService 子接口: 負責線程的調度 |--ScheduledThreadPoolExecutor : 繼承ThreadPoolExecutor,實現了ScheduledExecutorService
ExecutorService newFixedThreadPool() : 建立固定大小的線程池
ExecutorService newCachedThreadPool() : 緩存線程池,線程池的數量不固定,能夠根據需求自動的更改數量。
ExecutorService newSingleThreadExecutor() : 建立單個線程池。 線程池中只有一個線程
ScheduledExecutorService newScheduledThreadPool() : 建立固定大小的線程,能夠延遲或定時的執行任務併發
建立一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。ide
/** * 建立一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。 * 線程池爲無限大,當執行第二個任務時第一個任務已經完成,會複用執行第一個任務的線程,而不用每次新建線程。 * * @throws InterruptedException */ public static void cachedThreadPool() throws InterruptedException { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for(int i = 0; i < 10; i++) { final int index = i; // 加上這一行代碼,讓前面的線程執行完成,能夠看出,一直用的都是同一個線程,沒有新建 TimeUnit.SECONDS.sleep(1); cachedThreadPool.execute(() - > { System.out.println(Thread.currentThread() + "====" + index); }); } }
加上TimeUnit.SECONDS.sleep(1);執行結果:
一直複用的是同一個線程工具
Thread[pool-1-thread-1,5,main]====0 Thread[pool-1-thread-1,5,main]====1 Thread[pool-1-thread-1,5,main]====2 Thread[pool-1-thread-1,5,main]====3 Thread[pool-1-thread-1,5,main]====4 Thread[pool-1-thread-1,5,main]====5 Thread[pool-1-thread-1,5,main]====6 Thread[pool-1-thread-1,5,main]====7 Thread[pool-1-thread-1,5,main]====8 Thread[pool-1-thread-1,5,main]====9
去掉TimeUnit.SECONDS.sleep(1);執行結果:
建立了10個不一樣的線程性能
Thread[pool-1-thread-1,5,main]====0 Thread[pool-1-thread-2,5,main]====1 Thread[pool-1-thread-3,5,main]====2 Thread[pool-1-thread-4,5,main]====3 Thread[pool-1-thread-5,5,main]====4 Thread[pool-1-thread-6,5,main]====5 Thread[pool-1-thread-7,5,main]====6 Thread[pool-1-thread-9,5,main]====8 Thread[pool-1-thread-8,5,main]====7 Thread[pool-1-thread-10,5,main]====9
建立一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。線程
/** * 建立一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。 * 本例中,由於線程池大小爲3,每一個任務輸出index後sleep 2秒,因此每兩秒打印3個數字。 */ public static void fixedThreadPool() { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); for(int i = 0; i < 10; i++) { final int index = i; fixedThreadPool.execute(() - > { try { TimeUnit.SECONDS.sleep(2); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "====" + index); }); } }
執行結果:
由於線程池大小爲3,只會建立3個線程,每一個任務輸出index後sleep 2秒,因此每兩秒打印3個數字。code
Thread[pool-1-thread-1,5,main]====0 Thread[pool-1-thread-3,5,main]====2 Thread[pool-1-thread-2,5,main]====1 Thread[pool-1-thread-1,5,main]====3 Thread[pool-1-thread-3,5,main]====4 Thread[pool-1-thread-2,5,main]====5 Thread[pool-1-thread-1,5,main]====6 Thread[pool-1-thread-3,5,main]====7 Thread[pool-1-thread-2,5,main]====8 Thread[pool-1-thread-1,5,main]====9
建立一個定長線程池,支持定時及週期性任務執行。對象
/** * 建立一個定長線程池,延遲1秒,每隔1秒週期性任務執行 */ public static void scheduledThreadPool() { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2); scheduledThreadPool.scheduleAtFixedRate(() - > { System.out.println("scheduledThreadPool執行中..."); }, 1, 1, TimeUnit.SECONDS); }
執行結果:繼承
scheduledThreadPool執行中... scheduledThreadPool執行中... ...... scheduledThreadPool執行中... scheduledThreadPool執行中... ......
建立一個單線程化的線程池,它只會用惟一的工做線程來執行任務,保證全部任務按照指定順序(FIFO, LIFO, 優先級)執行。
/** * 建立一個單線程化的線程池,它只會用惟一的工做線程來執行任務,保證全部任務按照指定順序(FIFO, LIFO, 優先級)執行 */ public static void singleThreadExecutor() { ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); for(int i = 0; i < 10; i++) { final int index = i; singleThreadExecutor.execute(() - > { System.out.println(Thread.currentThread() + "====" + index); }); } }
執行結果:
只會建立一個線程
Thread[pool-1-thread-1,5,main]====0 Thread[pool-1-thread-1,5,main]====1 Thread[pool-1-thread-1,5,main]====2 Thread[pool-1-thread-1,5,main]====3 Thread[pool-1-thread-1,5,main]====4 Thread[pool-1-thread-1,5,main]====5 Thread[pool-1-thread-1,5,main]====6 Thread[pool-1-thread-1,5,main]====7 Thread[pool-1-thread-1,5,main]====8 Thread[pool-1-thread-1,5,main]====9