线程同步之Executor&ThreadPool基础

一、为什么要使用executor                                                                                                                                                                                                                                  

对于简单的任务来说,通常只需要将所需要完成的任务写在runnable中,并构造一个Thread即可。但是对于更大型、更复杂的应用,有必要将线程的创建和管理(creation and management)单独拎出来。executor是一个接口,它的实现类封装了这些功能,线程池是最常见的executor的实现。

java提供了以下三个接口:

  • Executor
  • ExecutorService  Executor的子接口,支持处理所需执行的任务以及executor本身的生命周期。
  • ScheduledExecutorService ExecutorService 的子接口,支持在任务的预后/间断执行。

executor简化了线程的创建和使用,比如通常的传入一个Runnable构造Thread并让其运行:

(new Thread(r)).start();
使用executor之后就可以写成:
e.execute(r);

根据Executor的实现,execute方法可能也只是像显示使用Thread类那样,创建线程并立即启动;但更多情况下,会使用一个存在的工作线程去运行runnable或者将runnable放置在一个队列中等待工作线程可用。ExecutorService以及ScheduledExecutorService的在Executor接口的基础上提供了更多功能。

二、线程池(ThreadPool)                                                                                                                                                                                                                               

绝大多数executor的实现都使用了包含工作线程的线程池,这种线程相对于其所执行的RunnableCallable是独立存在的。工作线程常被用于处理复杂的任务。

在大型应用里线程调度需要大量的内存管理工作,而使用工作线程省去了创建线程的麻烦。

fixed thread pool制定了运行的线程的数目—当一个线程在使用过程中被终止,会自动被一个新的线程所取代。任务经由一个内部队列传递到线程池,该内部队列存放着额外的任务(当任务数多于线程池规定的线程数)。

线程池的好处是能够让任务有序地被处理,而不会出现因为任务过多导致新线程不断地被创建导致资源耗竭。创建一个fixed thread pool使用java.util.concurrent.Executors中的newFixedThreadPool工厂方法即可还有其他的方法:

  • The newCachedThreadPool  创建一个线程池可以扩展的executor,适用于任务运行时间短、数目多的应用。
  • The newSingleThreadExecutor  创建一个每次只有一个任务被执行的executor。
  • ScheduledExecutorService 类中有上述个方法的相应的工厂方法。
原文地址:https://www.cnblogs.com/Russel/p/6008554.html