爲何引進線程池
魚池,咱們能夠釣出來一條再放回去,釣出來一條再放回去,這樣來撩魚。緩存
那線程池該如何玩呢?對,取出來一「條」線程,用完後再扔回去,再取出來,再扔....ide
線程池的優勢:性能
避免大量的建立和銷燬帶來的性能開銷線程
避免大量的線程間因互相搶佔系統資源致使的阻塞現象。設計
可以對線程進行簡單的管理並提供定時執行、間隔執行等功能。code
缺點對象
佔用必定的內存空間。接口
線程越多CPU的調度開銷越大。隊列
程序的複雜度會上升。內存
線程池的基本使用
使用線程池 ,確定要對「池」進行配置,像基本的池多大啊,能容納多少魚啊,等這些是須要建造前就要肯定的,所以咱們搞池以前先設計
• int corePoolSize 核心線程最大數
不管是閒置仍是工做中,永遠都不會銷燬的線程,會一直在線程池中存在,那咱們是否是永遠都奈何不了它呢,固然不會,把ThreadPoolExecutor的allowCoreThreadTimeOut這個屬性設置爲true,超過規定時長也會銷燬
• int maximumPoolSize 線程總數最大值
就是咱們全部的線程啊,對,包括非核心的和上邊講的核心的
• long keepAliveTime
若是不是核心線程,超過這個參數的時間就會被幹掉
• TimeUnit unit
時間老是有單位的吧,對就是上邊KeepAliveTime的時間參數哇
類型時枚舉,這裏舉幾種經常使用的,反正說多了也記不住,須要時候IDEA會提示
SECONDS : 秒
MINUTES : 分
HOURS : 小時
DAYS : 天
• BlockingQueue workQueue
隊列內容較多,咱們下邊單獨講
• ThreadFactory threadFactory
這個通常不用,不必管啦
• RejectedExecutionHandler handler
若是執行的過程當中,拋異常了,咱們能夠用這個來指定,可是系統有默認的,所以這個也能夠不用
使用線程池固然離不開Executor這個接口,具體的實現類在ThreadPoolExecutor中,so咱們簡單瞭解下這個類
//對,使用的就是這幾個構造,參數咱們上邊已經將過了
public class ThreadPoolExecutor extends AbstractExecutorService { ..... public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler); ... }
經常使用的幾種線程池
線程都池都是是使用Executors這個類建立出來的
• CachedThreadPool()
可緩存線程池:
線程數無限制
優先使用空閒線程,若是沒有才新建線程
//建立方式
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//源碼中的定義
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
• FixedThreadPool()
固定長度的線程池
能夠控制線程的數量
若是超過則必須排隊執行
//建立方式
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(線程數量);
//源碼中的定義
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
• ScheduledThreadPool()
對,就是它能夠定時
//建立方法
ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(最大線程數);
//源碼中的定義
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }
• SingleThreadExecutor()
全部任務排隊執行,一次只能執行一個任務
//建立方法ExecutorService singleThreadPool = Executors.newSingleThreadPool();
//源碼中的定義
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
隊列
隊列相似咱們的集合,實現了Collection接口
隊列中排隊執行的是咱們runnable對象
經常使用的隊列有以下幾種
• SynchronousQueue:
有任務來就執行交給空閒線程,若是沒有就新建線程執行,so 線程數設置儘量大即Integer.MAX_VALUE
• LinkedBlockingQueue:
永遠在覈心線程內使用線程,若是超過了核心的線程就在隊列中等待執行
• ArrayBlockingQueue:
優先使用核心線程數,其次使用非核心的,若是用完了就進入隊列等待
• DelayQueue:
想進入隊列必須實現Delayed接口,達到指定時間後,方可執行任務
讀書百遍不如代碼十遍,提高的惟一道路惟有你的手速!