以前建立線程的時候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()這三個方法。固然Executors也是用不一樣的參數去new ThreadPoolExecutorjava
1. newFixedThreadPool()函數
建立線程數固定大小的線程池。 因爲使用了LinkedBlockingQueue因此maximumPoolSize 沒用,當corePoolSize滿了以後就加入到LinkedBlockingQueue隊列中。每當某個線程執行完成以後就從LinkedBlockingQueue隊列中取一個。因此這個是建立固定大小的線程池。this
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
2.newSingleThreadPool()spa
建立線程數爲1的線程池,因爲使用了LinkedBlockingQueue因此maximumPoolSize 沒用,corePoolSize爲1表示線程數大小爲1,滿了就放入隊列中,執行完了就從隊列取一個。
線程
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
3.newCachedThreadPool()
code
建立可緩衝的線程池。沒有大小限制。因爲corePoolSize爲0因此任務會放入SynchronousQueue隊列中,SynchronousQueue只能存放大小爲1,因此會馬上新起線程,因爲maxumumPoolSize爲Integer.MAX_VALUE因此能夠認爲大小爲2147483647。受內存大小限制。繼承
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, 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.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
一、corePoolSize核心線程數大小,當線程數<corePoolSize ,會建立線程執行runnable隊列
二、maximumPoolSize 最大線程數, 當線程數 >= corePoolSize的時候,會把runnable放入workQueue中內存
三、keepAliveTime 保持存活時間,當線程數大於corePoolSize的空閒線程能保持的最大時間。get
四、unit 時間單位
五、workQueue 保存任務的阻塞隊列
六、threadFactory 建立線程的工廠
七、handler 拒絕策略
一、當線程數小於corePoolSize時,建立線程執行任務。
二、當線程數大於等於corePoolSize而且workQueue沒有滿時,放入workQueue中
三、線程數大於等於corePoolSize而且當workQueue滿時,新任務新建線程運行,線程總數要小於maximumPoolSize
四、當線程總數等於maximumPoolSize而且workQueue滿了的時候執行handler的rejectedExecution。也就是拒絕策略。
一、ThreadPoolExecutor.AbortPolicy() 直接拋出異常RejectedExecutionException
二、ThreadPoolExecutor.CallerRunsPolicy() 直接調用run方法而且阻塞執行
三、ThreadPoolExecutor.DiscardPolicy() 直接丟棄後來的任務
四、ThreadPoolExecutor.DiscardOldestPolicy() 丟棄在隊列中隊首的任務
固然能夠本身繼承RejectedExecutionHandler來寫拒絕策略.
int corePoolSize = 1; int maximumPoolSize = 2; int keepAliveTime = 10; // BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(); BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(5); ThreadFactory threadFactory = Executors.defaultThreadFactory(); //線程池和隊列滿了以後的處理方式 //1.跑出異常 RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy(); RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy(); RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy(); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2); for (int j = 1; j < 15; j++) { threadPoolExecutor.execute(new Runnable() { public void run() { try { System.out.println(Thread.currentThread().getName()); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }); } System.out.println(threadPoolExecutor); }