執行緒池各個引數講解
public ThreadPoolExecutor(int corePoolSize, //執行緒池核心工作執行緒數量,比如newFixedThreadPool中可以自定義的執行緒數量就是這個引數 int maximumPoolSize, //執行緒池所有工作執行緒的數量,比如newFixedThreadPool中的最大工作執行緒就是核心執行緒數,newCachedThreadPool中的最大工作執行緒數是Integer.MAX_VALUE long keepAliveTime, //非核心執行緒存活的時間,當核心執行緒不夠用的時候,建立出來的輔助工作執行緒在完成任務空閒多久後會被回收 TimeUnit unit, //上面一個引數的單位,分。秒等 BlockingQueue<Runnable> workQueue,//底層使用的阻塞佇列資料結構,比如newFixedThreadPool底層使用LinkedBlockingQueue。工作佇列,儲存已提交但是未執行的任務 ThreadFactory threadFactory, //建立工作執行緒的工廠,保持預設即可 RejectedExecutionHandler handler) { //拒絕策略,即在所有工作執行緒數達到上限,底層阻塞佇列也滿了的時候採取的策略 if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
常用執行緒池
日常使用中使用哪種執行緒池
上面四種都不使用,我們需要通過ThreadPoolExcutor自定義執行緒池,阿里巴巴java開發手冊明確指出,不允許使用Excutors工具類進行執行緒池的建立,因為某些開發人員不瞭解底層執行規則,避免資源耗盡的危險
1:FixedThreadPool 和 SingleThreadPool: 允許的請求佇列(底層實現是LinkedBlockingQueue)長度為Integer.MAX_VALUE,可能會堆積大量的請求,從而導致OOM
2:CachedThreadPool 和 ScheduledThreadPool 允許的建立執行緒數量為Integer.MAX_VALUE,可能會建立大量的執行緒,從而導致OOM
執行緒池4種拒絕策略
new ThreadPoolExecutor.AbortPolicy(); //遇到執行緒池達到最大執行緒數,且佇列已經滿了,直接拋異常 ----預設
new ThreadPoolExecutor.DiscardOldestPolicy() //遇到執行緒池達到最大執行緒數且佇列已經滿了,則丟棄佇列中最前面的任務,
new ThreadPoolExecutor.DiscardPolicy() //遇到執行緒池達到最大執行緒數且佇列已經滿了,丟棄當前任務,不給它加入佇列中
new ThreadPoolExecutor.CallerRunsPolicy();//會將任務返回給提交者進行執行,比如讓main執行緒直接執行run方法
執行緒池優點
1.避免大量執行緒的建立銷燬帶來的效能開銷
2.避免大量執行緒之間因為相互搶佔系統資源導致的阻塞狀態
3.能夠對執行緒進行簡單的管理並提供定時執行,間隔執行等功能
在IO密集型和CPU密集型下執行緒池最大執行緒數選擇
在CPU密集型下,選用cpu核心數+1作為最大執行緒池工作執行緒數量,減少cpu切換任務帶來的開銷
在IO密集型下,儘可能多的加大工作執行緒數量,一般為cpu核心數*2
執行緒池提交任務時excute和submit有什麼區別
1.兩者接收引數不一致,excute接收Runnable介面,submit接收Callable介面
2.submit有返回值,execute沒有返回值
3.submit支援返回Future
執行緒池狀態
private static final int RUNNING = -1 << COUNT_BITS; private static final int SHUTDOWN = 0 << COUNT_BITS; private static final int STOP = 1 << COUNT_BITS; private static final int TIDYING = 2 << COUNT_BITS; private static final int TERMINATED = 3 << COUNT_BITS;
RUNNING:執行緒池的初始狀態,可以新增待執行的任務
SHUTDOWN:執行緒池處於待關閉狀態,不接受新任務,但會處理完已接收的任務
STOP:執行緒池立即關閉,不接收新的任務,放棄快取佇列中的任務並且中斷正在處理的任務
TIDYING:執行緒池自主整理狀態,呼叫 terminated() 方法進行執行緒池整理
TERMINATED:執行緒池終止狀態