详解Executors构建线程池

Executors
Execcutors提供了一些方便创建ThreadPooleExecutor的方法,主要有:

newFixedThreadPool(int)
创建固定大小的线程池,线程KeepAliveTime为0,默认情况 下,ThreadPoolExecutor中启动的CorePoolSize数量的线程启动后就一直运行,并不会邮于keepAliveTime时间到达后仍没有任务需要执行就退出。缓冲 任务的队列为LinkedBlockingQueue,大小为整形的最大数。当使用此线程池时,在同时执行的Task数量 超过传入的线程池的大小值后,将会放入linkedBlockingQueue,在linkedBlockingQueue中的Task需要等待线程空闲后来执行,当放入linkedBlocking Queue中的Task超过整型最大数时,抛出RejectedExecutionException。

newSingleThreadExecutor()
相当于创建 大小为1单位的固定线程池,当使用此线程池时,同时执行的Task只有1个,其它 的Task都在LinkedBlockingQueue中。

newCachedThreadPool()
创建 CorePoolSize为0,最大线程数为整形的最大数,线程KeepAliveTime为1分钟,缓存任务的队列为SynchronousQueue的线程池。在使用时,放入线程池的Task都会利用线程或启动新线程来执行,直到启动的线程数达到整形最大数据后执行RejectedExecutionException启动后的线程存活时间为1分钟。

NewScheduledThreadPool(int)
创建 corepoolsize为传入参数,最大线程数为整型的最大数,线程keepAliveTime为0,缓存任务的队列为DelayedWorkQueue的线程池。在实际业务中,通常会有一些需要定时或延迟执行的任务,而对于分布式JAVA应用而言,更为典型的则是在异步操作需要超时回调的场景。这种情况下scheduledThreadPoolExecuotr是不错的选择,在JDK5以前的版本中更多的是借助Timer来实现,Timer和SchedUledThreadPoolExecutor主要有以下三方面区别:

1、Timer 只能单线程,一旦Task执行缓慢,变会导致其它的task执行推迟,而如果使用scheduledThreadPoolExecutor,则可自行控制线程数。

2、当Timer中的task抛出RuntimeExecption时,会导致Timer中所有的task不再执行.

3、ScheduledThreadPoolExecutor可执行Callable的Task,从而执行完毕后得到执行结果 。

当要执行Runnable和Callable的Task加入时,ScheduledThreadPoolExecutor会将其放入内部的DelayEdWorkQueue中,DelayedWork Queue 又基于DelayQueue来实现;当有新的Task加入时,DelayQueue会将其加入内部的数组对象中,并进行执行排序。对于ScheduledThreadPoolExecutor而言,排序的规则为执行的时间。执行时间越近的排在越前,线程池中的线程在获取要执行的Task时,方式为获取最近要执行的Task,并调用Condition的awaiNanos 来等待唤醒。ScheduledThreadPoolExecutor和Timer一样,无法确保task在指定的延时时间点执行,这主要是由于到达时间点的时候 CPU可能没有高度到执行Task线程。

你可能感兴趣的:(Executors)