java Executor, ExecutorService, Executors 有什么不同
Executor 是一个接口,只定义了一个方法, 可以接收Runnable实例,用来执行一个实现Runnable接口的任务。 void execute(Runnable command); ExecutorService 也是一个接口,继承自Executor,并增加了一些方法,用的比较广泛,提供了一些生命周期的方法。shutdown,还有submit方法返回值是future。 ExecutorService就是为了解决执行服务的生命周期问题的。ExecutorService的生命周期有3种状态:运行,关闭和已终止。 在初始创建时处于运行状态。 Shutdown方法将执行平缓的关闭过程;不再接受新的任务,同时等待已经提交的任务执行完成——包括那些还未开始执行的任务。 Shutdownnow方法将执行粗暴的关闭过程,它将尝试取消所有运行中的任务,并且不再启动队列中尚未开始执行的任务。 等所有任务都完成后,ExecutorService将转入终止状态。 可以调用awaitTermination来等待ExecutorService到达终止状态。 通过isTerminated来轮询ExecutorService是否已经终止。 1 void shutdown(); 2 List<Runnable> shutdownNow(); 3 boolean isShutdown(); 4 boolean isTerminated(); 5 boolean awaitTermination(long timeout,TimeUnit unit) 6 throws InterruptedException; 7 <T> Future<T> submit(Callable<T> task); 8 <T> Future<T> submit(Runnable task,T result); 9 Future<?> submit(Runnable task); 10 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) 11 throws InterruptedException; 12 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,13 long timeout,TimeUnit unit) 14 throws InterruptedException; 15 <T> T invokeAny(Collection<? extends Callable<T>> tasks) 16 throws InterruptedException,ExecutionException; 17 <T> T invokeAny(Collection<? extends Callable<T>> tasks,18 long timeout,TimeUnit unit) 19 throws InterruptedException,ExecutionException,TimeoutException; ? Executors 是静态工厂类,可以用它创建出各种各样的线程池。 一般像下面这么用。 ScheduledExecutorService service=Executors.newScheduledThreadPool(int corePoolSize);? 1 public static ExecutorService newFixedThreadPool(int nThreads) { 2 return new ThreadPoolExecutor(nThreads,nThreads, 3 0L,TimeUnit.MILLISECONDS, 4 new LinkedBlockingQueue<Runnable>()); 5 } 6 7 public static ExecutorService newSingleThreadExecutor() { 8 return new FinalizableDelegatedExecutorService 9 (new ThreadPoolExecutor(1,1,10 0L,11 new LinkedBlockingQueue<Runnable>())); 12 } 13 public static ExecutorService newCachedThreadPool() { 14 return new ThreadPoolExecutor(0,Integer.MAX_VALUE,15 60L,TimeUnit.SECONDS,16 new SynchronousQueue<Runnable>()); 17 } 18 public static ScheduledExecutorService newSingleThreadScheduledExecutor() { 19 return new DelegatedScheduledExecutorService 20 (new ScheduledThreadPoolExecutor(1)); 21 } 22 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { 23 return new ScheduledThreadPoolExecutor(corePoolSize); 24 } 25 public static ScheduledExecutorService newScheduledThreadPool( 26 int corePoolSize,ThreadFactory threadFactory) { 27 return new ScheduledThreadPoolExecutor(corePoolSize,threadFactory); 28 } 可以看到 newScheduledThreadPool(int corePoolSize,ThreadFactory threadFactory) 这个方法可以传入线程池的大小,线程工厂,这里表明,我们可以自己实现一个工厂来创建所需要的线程池。 我们想想问什么要有Executor,ExecutorService这些类。我们用Thread类不行吗。 在java类库中,任务执行的主要抽象不是Thread,而是Executor, 它提供了一种标准的方法将任务的提交过程与执行过程解耦开来,并用Runnable来表示任务。Executor的实现还提供了对生命周期的支持,以及统计信息收集,应用程序管理机制和性能监视等机制。 执行策略:通过将任务的提交与执行解耦开来,从而无须太大的困难就可以为某种类型的任务指定和修改执行策略。在执行策略中定义了任务执行的what,where,when,how等方面,包括: 在什么(what)线程中执行任务 任务按照什么(what)顺序执行(FIFO,LIFO,优先级) 有多少个(How many)任务能并发执行 在队列中有多少个(how many)任务在等待执行 如果系统由于过载而需要拒绝一个任务,那么应该选择哪一个(which) 任务?另外,如何(how)通知应用程序有任务被拒绝? 在执行一个任务之前或之后,应该进行哪些(what)动作? 各种执行策略都是一种资源管理工具,最佳策略取决于可用的计算资源以及对服务质量的需求。通过限制并发任务的数量,可以确保应用程序不会由于资源耗尽而失败,或者由于在稀缺资源上发生竞争而严重影响性能。通过将任务的提交与任务的执行策略分离开来,有助于在部署阶段选择与可用硬件资源最匹配的执行策略。 ?线程池:好处: 在线程池中执行任务比为每个任务分配一个线程优势更多。通过重用现有的线程而不是创建线程,可以在处理多个请求时分摊在线程创建和销毁过程中产生的开销。另一个好处是,当请求到达时,工作线程通常已经存在,因此不会因为等待创建线程而延迟任务的执行。 下面是Executors可以创建的各种线程池。(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |