创建一个固定数量的线程池,用于处理多个任务
ExecutorService executorService = Executors.newFixedThreadPool(3); public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }创建一个只有一个线程的线程池。
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); }创建可以缓存的线程池,这个缓存的意义就在于设置了一个线程的 60秒 的存活时间
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }在上面的构造方法中,我们发现都会调用了 ThreadPoolExecutor(五个参数) 方法,其实 ThreadPoolExecutor 方法只是简易版本,它里面还有调用 ThreadPoolExecutor (七个参数) 的方法,下面我们来看看参数的含义:
int corePoolSize:线程池当中所一直维护的线程数量,如果线程池处于任务空闲期间,那么该线程也并不会被回收掉(设置方法:CPU核心数) int maximumPoolSize:线程池当中所维护的线程数的最大数量 long keepAliveTime:超过了 corePoolSize 的线程在经过 keepAliveTime 时间后如果一直处于空闲状态,那么超过的这部分线程将会被回收掉 TimeUnit unit:keepAliveTime 的时间单位 BlockingQueue workQueue:向线程池所提交的任务位于的阻塞队列,它的实现有多种方式 ThreadFactory threadFactory:线程工厂,用于创建新的线程并被线程池所管理,默认线程工厂所创建的线程都是用户线程且优先级为正常优先级 RejectedExecutionHandler handler:表示当线程池中的线程都在忙于执行任务且阻塞对垒也已经满了的情况下,新到来的任务该如何被对待和处理 AbortPolicy: 直接抛出一个运行期异常 DiscardPolicy: 默默地丢弃掉提交的任务,什么都不做且不抛出任何异常 DiscardOldestPolicy: 丢弃掉阻塞队列中存放时间最久的任务(对头元素),并且为当前所提交的任务留出一个队列中的空闲空间,以便将其放进队列中 CallerRunsPolicy: 直接由提交任务的线程来运行这个提交的任务
线程池一共存在5种状态:
RUNNING:线程池可以接受新的任务提交,并且还可以正常处理阻塞队列中的任务SHUTDOWN:不再接收新的任务,不过线程池可以继续处理阻塞队列中的任务STOP:不再接收新的任务,同时还会丢弃阻塞队列中的现有任务;此外,他还会中断正在处理中的任务TIDYING:所有的任务都执行完毕后(同时也涵盖了阻塞队列中的任务),当前线程池中的活动的线程数量降为 0 ,将会调用terminated 方法TERMINATED:线程池的终止状态,当terminated 方法执行完毕后,线程池将会处于该状态之下线程池的状态变化:
RUNNING -> SHUTDOWN:当调用了线程池的shutdown方法,或者当finalize方法时被隐式调用后RUNNING、SHUTDOWN -> STOP:当调用了线程池的shutdownNow方法时SHUTDOWN -> TIDYING:在线程池与阻塞队列均变为空时STOP -> TIDYING:在线程池变为空时TIDYING -> TERMINATED:在terminated 方法被执行完毕时关于线程池的总体执行策略: 7. 如果线程池中正在执行的线程数 < corePoolSize,那么线程池就会优先选择创建新的线程而非将提交的任务添加到阻塞队列中 8. 如果线程池中正在执行的线程数 >= corePoolSize,那么线程池就会优先选择对提交的任务添加到阻塞队列中而非创建新的线程 9. 如果提交的任务无法添加到阻塞队列中,那么线程池就会创建新的线程;如果创建的线程数超过了 maximumPoolSize,那么拒绝策略就会起作用
