Executors:Java自1.5之后提供了对线程池的创建工厂,返回的对象类型是ExecutorService,它提供了两个执行的方法,一个是
submit(Runnable task)另一个是execute(Runnable command),二者都接受一个线程进行参数的传入。
常用的线程池主要有以下4个:
创建出的线程池,默认不创建线程,但是可放置最多Integer.MAX_VALUE个线程,每个线程有60S的生命周期,如果没有用到就释放
newCachedThreadPool() 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们 |
创建的线程池,具有固定数量,超过则放置到LinkedBlockingQueue中,不另外创建新线程,等待有线程可用时,再进行调用
newFixedThreadPool(int nThreads) 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。 |
创建的线程池,需要传入一个指定大小的参数,在合适的时间进行运行,返回的对象类型是ExecutorService的子类ScheduledExecutorService,需要调用schdule方法进行指定在什么时候使用
newScheduledThreadPool(int corePoolSize) 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 |
创建一个只有单线程的线程池
newSingleThreadExecutor() 创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。 |
自定义线程池
上述所有的线程的创建方式,都可以通过手动的方式去创建,他们内部都是使用了ThreadPoolExecutor来创建的
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
这是ThreadPoolExecutor的构造方法,一共具有6个参数,分别是默认线程数,最大线程数,是否保持可连接,时间单位,阻塞队列,拒绝方式
看看FixedThreadPool是怎么创建的吧:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
根据传入的线程个数,初始化对应的线程数,最大线程也为初始化线程,延时不消失,新的任务如果线程消化不了放到LinkedBlockingQueue中进行保存,没有选择拒绝方式,为默认的拒绝方式,就是报错之后,其他的线程继续执行,jdk默认一共有四种拒绝方式,都在ThreadPoolExecutor中,属于静态属性,可直接调用
static class | ThreadPoolExecutor.AbortPolicy 用于被拒绝任务的处理程序,它将抛出 RejectedExecutionException. |
static class | ThreadPoolExecutor.CallerRunsPolicy 用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务。 |
static class | ThreadPoolExecutor.DiscardOldestPolicy 用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试 execute;如果执行程序已关闭,则会丢弃该任务。 |
static class | ThreadPoolExecutor.DiscardPolicy 用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。 |