目錄
- 線程池
- 什么是線程池?
- 為什么用線程池?
- 線程池原理
- 常見四種線程池和自定義線程池
線程池
什么是線程池?
池化技術
為什么用線程池?
1 由于設置最大線程數,防止線程過多而導致系統崩潰。
2 線程復用,不需要頻繁創建或銷毀線程,并且銷毀和創建是耗費時間和資源操作,所以提高了效率,節約資源。
線程池原理
核心線程,等待隊列,非核心線程,拒絕策略
如果有空閑的線程直接使用,沒有空閑的線程并且線程數量未達到corePoolSize,則新建一個線程(核心線程)執行任務
線程數量達到了corePoolSize,則將任務移入隊列等待空閑線程將其取出去執行(通過getTask() 方法從阻塞隊列中獲取等待的任務,如果隊列中沒有任務,getTask()方法會被阻塞并掛起,不會占用cpu資源,整個getTask操作在自旋下完成)
隊列已滿,新建線程(非核心線程)執行任務,空閑下來以后,非核心線程會按照時間策略進行銷毀
隊列已滿,總線程數又達到了maximumPoolSize,就會執行任務拒絕策略。
handler:表示當拒絕處理任務時的策略(①AbortPolicy丟棄任務并拋出RejectedExecution異常;②DiscardPolicy丟棄任務,但是不拋出異常;③DiscardOldestPolicy丟棄隊列最前面的任務,然后重新嘗試執行任務;④CallerRunsPolicy由調用線程處理該任務)
常見四種線程池和自定義線程池
見文檔
代碼
PoolTest1
public class PoolTest1 {public static void main(String[] args) {
// ExecutorService executorService1 = Executors.newCachedThreadPool();
// ExecutorService executorService2 = Executors.newFixedThreadPool(5);
// ExecutorService executorService3 = Executors.newSingleThreadExecutor();
// ScheduledExecutorService executorService4 = Executors.newScheduledThreadPool(5);ThreadPoolExecutor executorService = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.AbortPolicy());// 執行任務-線程不用我們創建,交給線程池管理,只需要把執行邏輯放進去就OKfor (int i = 0; i < 20; i++) {int finalI = i;executorService.execute(new Runnable() {@Overridepublic void run() {System.out.println("Thread Name: "+Thread.currentThread().getName()+" I="+ finalI);try {Thread.sleep(5*1000);} catch (InterruptedException e) {e.printStackTrace();}}});}executorService.shutdown();}
}
MyTask
public class MyTask implements Callable<String> {private Integer integer1;private Integer integer2;public MyTask(Integer integer1,Integer integer2){this.integer1 =integer1;this.integer2 =integer2;}@Overridepublic String call() throws Exception {int i = integer1 + integer2;return "Thread name:" + Thread.currentThread().getName()+" i="+i;}
}
PoolTest2
public class PoolTest2 {public static void main(String[] args) throws ExecutionException, InterruptedException {
// ExecutorService executorService1 = Executors.newCachedThreadPool();
// ExecutorService executorService2 = Executors.newFixedThreadPool(5);
// ExecutorService executorService3 = Executors.newSingleThreadExecutor();
// ScheduledExecutorService executorService4 = Executors.newScheduledThreadPool(5);ThreadPoolExecutor executorService = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.AbortPolicy());// 執行任務-線程不用我們創建,交給線程池管理,只需要把執行邏輯放進去就OKArrayList<Future<String>> futures = new ArrayList<>();for (int i = 0; i < 20; i++) {MyTask myTask = new MyTask(3,4);Future<String> future = executorService.submit(myTask);// future.get()為myTask.call()的返回值futures.add(future);}List<String> resutlts = new ArrayList<>();for (int i = 0; i < futures.size(); i++) {String resutlt = futures.get(i).get();resutlts.add(resutlt);}System.out.println("===="+resutlts.get(19));executorService.shutdown();}
}