線程池
線程池的思想
線程池的概念與Executors類的應用
> 創建固定大小的線程池
> 創建緩存線程池
> 創建單一線程池(如何實現線程死掉后重新啟動?)
關閉線程池
> shutdown 與 shutdownNow的比較
用線程池啟動定時器
> 調用ScheduleExecutorService 的 schedule 方法,返回的ScheduleFuture對象可以取消任務。
> 支持間隔重復任務的定時方式,不直接支持決定定時的方法,需要轉換成相對時間方式。
public class ThreadPoolTest { public static void main(String[] args) { // ExecutorService threadPool = Executors.newFixedThreadPool(3); //創建一個固定大小的線程池,線程池中有3個線程可以同時服務 //緩存線程池 線程池中的線程數是動態變化的,當所有線程處於服務狀態時,還有需要被服務的任務,自動增加一個線程進行服務 //當任務執行完畢,線程處於空閑一段時間,超時后則自動回收銷毀線程 // ExecutorService threadPool = Executors.newCachedThreadPool(); //創建一個只有一個線程的線程池,當這個線程掛掉時,可以自動生成一個線程來代替 //可以解決一個網上很多人問的問題(如何實現線程死掉后重新啟動?) ExecutorService threadPool = Executors.newSingleThreadExecutor(); for(int i = 0;i<10;i++){ //往線程池中扔10個任務 final int task = i; threadPool.execute(new Runnable() { //往線程池中扔了一個任務 @Override public void run() { for(int j = 0;j<10;j++){ System.out.println(Thread.currentThread().getName()+" is loop of "+ j + "the task of "+task); } } }); } System.out.println("all of 10 tasks have committed"); //上述代碼執行完后 沒有結束,線程池中有3個線程一直存在,所以程序不會結束 //可以使用 threadPool.shutdown() threadPool.shutdown(); //當線程池中線程執行完所有任務,所有線程處於空閑狀態時,干掉所有線程,程序自結束 // threadPool.shutdownNow(); //立即把池子中所有線程干掉,無論任務是否干完 } }
package com.java.juc; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 一、線程池:提供了一個線程隊列,隊列中保存着所有等待狀態的線程。避免了創建與銷毀額外的開銷,提高了響應的速度。 * * 二、線程池的體系結構: * java.util.concurrent.Executor: 負責線程的使用與調度根接口。 * |--**ExecutorService 子接口:線程池的主要接口 * |--ThreadPoolExecutor 線程池的實現類 * |--ScheduledExecutorService 子接口:負責線程的調度 * |--ScheduledThreadPoolExecutor : 繼承 ThreadPoolExecutor 實現ScheduledExecutorService * 三、工具類:Executors * ExecutorService newFixedThreadPool() :創建固定大小的線程池。 * ExecutorService newCachedThreadPool(): 創建無限大小的線程池,線程池中線程數量不固定,可根據需求自動更改。 * ExecutorService newSingleThreadPool() : 創建單個線程池,線程池中只有一個線程。 * * ScheduledExecutorService newScheduledThreadPool() 創建固定大小的線程池,可以延遲或定時的執行任務。 * */ public class TestThreadPool { public static void main(String[] args) { //1.創建線程池 ExecutorService threadPool = Executors.newFixedThreadPool(5); ThreadPoolDemo demo = new ThreadPoolDemo(); //2.為線程池中的線程分配任務 for(int i = 0;i<10;i++){ threadPool.submit(demo); } //3.關閉線程池 threadPool.shutdown(); //等待現有線程池中的任務之心完畢,關閉線程池,在等待過程中不接收新的任務 } } class ThreadPoolDemo implements Runnable{ private int i = 0; @Override public void run() { while(i <= 100){ System.out.println(Thread.currentThread().getName() + " : " + i++); } } }
可以在線程池中放一個Callable任務,並且可以過去到返回結果
package com.java.juc; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * 一、線程池:提供了一個線程隊列,隊列中保存着所有等待狀態的線程。避免了創建與銷毀額外的開銷,提高了響應的速度。 * * 二、線程池的體系結構: * java.util.concurrent.Executor: 負責線程的使用與調度根接口。 * |--**ExecutorService 子接口:線程池的主要接口 * |--ThreadPoolExecutor 線程池的實現類 * |--ScheduledExecutorService 子接口:負責線程的調度 * |--ScheduledThreadPoolExecutor : 繼承 ThreadPoolExecutor 實現ScheduledExecutorService * 三、工具類:Executors * ExecutorService newFixedThreadPool() :創建固定大小的線程池。 * ExecutorService newCachedThreadPool(): 創建無限大小的線程池,線程池中線程數量不固定,可根據需求自動更改。 * ExecutorService newSingleThreadPool() : 創建單個線程池,線程池中只有一個線程。 * * ScheduledExecutorService newScheduledThreadPool() 創建固定大小的線程池,可以延遲或定時的執行任務。 * */ public class TestThreadPool { public static void main(String[] args) throws InterruptedException, ExecutionException { //1.創建線程池 ExecutorService threadPool = Executors.newFixedThreadPool(5); ThreadPoolDemo demo = new ThreadPoolDemo(); List<Future> futureList = new ArrayList<>(); for(int i = 0; i<10; i++){ Future<Integer> future = threadPool.submit(new Callable<Integer>() { public Integer call(){ int num = 0; for(int i = 0;i<=100;i++){ num+=i; } return num; } }); futureList.add(future); } for(int i = 0;i<futureList.size();i++){ System.out.println(futureList.get(i).get()); } // //2.為線程池中的線程分配任務 // for(int i = 0;i<10;i++){ // threadPool.submit(demo); // } //3.關閉線程池 threadPool.shutdown(); //等待現有線程池中的任務之心完畢,關閉線程池,在等待過程中不接收新的任務 } } class ThreadPoolDemo implements Runnable{ private int i = 0; @Override public void run() { while(i <= 100){ System.out.println(Thread.currentThread().getName() + " : " + i++); } } }
5050
5050
5050
5050
5050
5050
5050
5050
5050
5050
用線程池啟動定時器
Executors.newScheduledThreadPool(3).schedule( new Runnable() { @Override public void run() { System.out.println("bombing!"); } }, 10, TimeUnit.SECONDS);
還可以在上述代碼中添加固定頻率
//固定頻率 10秒后觸發,每隔兩秒后執行一次 Executors.newScheduledThreadPool(3).scheduleAtFixedRate( new Runnable() { @Override public void run() { System.out.println("bombing!"); } }, 10, 2, TimeUnit.SECONDS); //在使用scheduleAtFixedRate 時java api沒有提供在某個時間點觸發,但API中提示可以通過計算,得到觸發的事件點 // For example, to schedule at a certain future date, // you can use: schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS).