利用Executor框架执行并行任务---之基础篇
??? 本文章的主题主要是在应用程序中寻找可以并行的任务,也就是把问题分成几个子问题。
?
一、讲解Executor和Executors以及ThreadPoolExecutor
?
public interface Executor{void execute(Runnable command) ; }
?
??? 执行已提交的 Runnable
任务的对象。
?
? Executors是一个工厂类,它创建不同类型的线程池,主要是根据不同的参数配置。
?
下面还是主要说明ThreadPoolExecutor类中的构造方法,如:
?
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
?
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
?2、
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
?创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。
二、讲解ExecutorService
由于创建了线程池说明是一个非常复杂的程序,所以就需要对它进行管理,也就是说他们的生命周期。
ExecutorService是Executor的父类,它定义了一个灵活的执行策略以及对任务的批量处理,讲解这个接口之前,需要讲解一下Future接口和Callable接口。
public interface Future<V>
?
?
Future<V> f = cache.get(arg); if (f == null) { Callable<V> eval = new Callable<V>() { public V call() throws InterruptedException { return c.compute(arg); } }; FutureTask<V> ft = new FutureTask<V>(eval); f = ft; cache.put(arg, ft); ft.run(); // call to c.compute happens here } try {
return f.get();
?执行任务还有另外一个方法就是委托给线程:new Thread(ft).start()
?
下面讲解ExecutorService接口:
?
由于Executor接口一次只能执行一个任务对多个任务不支持,而且对任务执行中参数的异常不可以管理以及取消提交的任务都不支持,对于以上的需求,就扩展了ExecutorService接口。
?
?
?
public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
自从Executor引进了Service后,该应用就能提供一种优雅的方式关闭应用程序,并且提供一些影响关闭状态的消息。
?
ExecutorService生命周期有三个状态:运行状态、正在关闭状态、终止状态,他是刚刚创建的时候就是运行状态。
?shutdow方法允许已经被提交的任务被执行但是不接收新的任务;shutdownNow方法是立即关闭:试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
?
invokeAll方法时批量的提交任务返回一个future集合,这个方法在下面的文章能应用。。。