执行器简介
Java 实现并发应用程序的基本机制如下。
-
实现了 Runnable 接口的类:这是要以并发方式实现的代码。
-
Thread 类的一个实例:这是将以并发方式执行该代码的线程。
这种方式可以创建并管理 Thread 对象,并且实现线程间的同步机制。
然而,这也会带来一些问题,尤其对那些具有大量并发任务的应用程序来说更是如此。
如果线程太多,就会降低应用程序性能,甚至会使整个系统中断运行。
Java 5 引入了执行器框架解决这些问题,并且提供了一个高效的解决方案,相对于传统并发机制而言,该解决方案更便于编程人员使用。
执行器的基本特征
执行器的主要特征如下。
-
不需要创建任何 Thread 对象
如果要执行一个并发任务,只需要创建一个执行该任务的实例并且将其发送给执行器。执行器会管理执行该任务的线程。 - 执行器通过重新使用线程来缩减线程创建带来的开销
在内部,执行器管理着一个线程池,其中的线程称为工作线程(worker-thread)。
如果向执行器发送任务而且存在某一空闲的工作线程,那么执行器就会使用该线程执行任务。 - 使用执行器控制资源很容易
可以限制执行器工作线程的最大数目。
如果发送的任务数多于工作线程数,那么执行器就会将任务存入一个队列。
当工作线程完成某个任务的执行后,将从队列中调取另一个任务继续执行。 - 必须以显式方式结束执行器的执行,必须告诉执行器完成执行之后终止所创建的线程
如若不然,执行器则不会结束执行,这样应用程序也不会结束。
执行器框架的基本组件
执行器框架中含有各种接口和类,它们可实现执行器提供的全部功能。
该框架的基本组件如下:
-
Executor 接口
这是 Executor 框架的基本接口。
它仅定义了一个方法,即允许编程人员向执行器发送一个 Runnable 对象。 - ExecutorService 接口
该接口扩展了 Executor 接口并且包括更多方法,增加了该框架的功能,例如以下所述。- 执行可返回结果的任务:
Runnable 接口提供的 run() 方法并不会返回结果,但是借用执行器,任务可以返回结果。 - 通过单个方法调用执行一个任务列表。
- 结束执行器的执行并且等待其终止。
- 执行可返回结果的任务:
- ThreadPoolExecutor 类
该类实现了 Executor 接口和 ExecutorService 接口。
此外,它还包含一些其他获取执行器状态(工作线程的数量、已执行任务的数量等)的方法、确定执行器参数(工作线程的最小和最大数目、空闲线程等待新任务的时间等)的方法,以及支持编程人员扩展和调整其功能的方法。 - Executors 类
该类为创建 Executor 对象和其他相关类提供了实用方法。