以前建立线程的时候都是用的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); }