欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Executor框架

程序员文章站 2022-04-20 11:04:54
...

       Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。框架结构图如下:


Executor框架
            
    
    博客分类: 多线程-同步 java多线程executor

 

       使用Executor来执行多个线程的好处是用来避免线程的创建和销毁的开销,以提升效率。因此如果某些场景需要反复创建线程去处理同类事务的话,可以考虑使用线程池来处理。

 

一、创建ExecutorService

       Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。Executors下获取ExecutorService 的方法有很多,如单线程线程池、固定线程数的线程池等,不过最终还是调用ExecutorService的构造函数来创建,如下:

public ThreadPoolExecutor(int corePoolSize,//核心线程数
                          int maximumPoolSize,//最大线程数
                          long keepAliveTime,//线程保持活动的时间,该时间就是超过核心池大小的线程可以在终止前保持空闲的时间值。
                          TimeUnit unit,//等待时间的单位
                          BlockingQueue<Runnable> workQueue,//等待线程队列
                          ThreadFactory threadFactory)//线程生产工厂   

      通过以上方法就可以创建一个线程池,可以限制线程的数量和等待队列中线程的等待时间等。

 

Executors提供以下静态工厂方法创建一个线程池:

public static ExecutorService newFixedThreadPool(int nThreads)

创建一个定长的线程池。达到最大线程数后,线程数不再增长,新增任务保存在workQueue中。如果一个线程由于非预期Exception而结束,线程池会补充一个新的线程。

 

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

 

public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor。

 

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,可用来替代Timer类。

Timer是基于绝对时间,对系统时钟的改变是敏感的,而ScheduledThreadPoolExecutor只支持相对时间。
1) Timer是创建唯一的线程来执行所有的timer任务。如果一个任务超时了,会导致其他的TimerTask时间准确性出问题。
2)如果TimerTask抛出uncheck 异常,Timer将会产生无法预料的行为。因此,ScheduledThreadPoolExecutor可以完全代替Timer。
 

 二、ExecutorService生命周期

      为了解决执行服务的生命周期问题,ExecutorService接口扩展了Executor,提供了三种状态,运行 ,关闭 ,终止。Executor创建时处于运行状态。当调用ExecutorService.shutdown()后,处于关闭状态,isShutdown()方法返回true。这时,不应该再想Executor中添加任务,所有已添加的任务执行完毕后,Executor处于终止状态,isTerminated()返回true。如果Executor处于关闭状态,往Executor提交任务会抛出unchecked exception RejectedExecutionException。

 

 三、使用Callable,Future返回结果

       Future<V>代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞。FutureTask<V>实现了Future<V>和Runable<V>。Callable代表一个有返回值得操作。

       ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

 

 四、CompletionService

        将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者 submit 执行的任务。使用者 take 已完成的任务,并按照完成这些任务的顺序处理它们的结果。

       通常,CompletionService 依赖于一个单独的 Executor 来实际执行任务,在这种情况下,CompletionService 只管理一个内部完成队列。ExecutorCompletionService 类提供了此方法的一个实现。