Executor 框架 |
java.util.concurrent
包中包含灵活的线程池实现,但是更重要的是,
它包含用于管理实现 Runnable
的任务的执行的整个框架。该框架称为
Executor 框架。
Executor
接口相当简单。它描述将运行Runnable
的对象:
public interface Executor {
void execute(Runnable command);
}
任务运行于哪个线程不是由该接口指定的,这取决于使用的 Executor
的实现。
它可以运行于后台线程,如 Swing 事件线程,或者运行于线程池,或者调用
线程,或者新的线程,它甚至可以运行于其他 JVM!通过同步的 Executor
接口提交任务,从任务执行策略中删除任务提交。Executor
接口独自关注任
务提交 —— 这是 Executor
实现的选择,确定执行策略。这使在部署时调整
执行策略(队列限制、池大小、优先级排列等等)更加容易,更改的代码最少。
Executor |
更可靠的 Web 服务器 —— 使用 Executor
java.util.concurrent
包包含多个Executor
实现,每个实现都实现不
同的执行策略。什么是执行策略?执行策略定义何时在哪个线程中运行任务,
执行任务可能消耗的资源级别(线程、内存等等),以及如果执行程序超载
该怎么办。 执行程序通常通过工厂方法例示,而不是通过构造函数。Executors
类包含用于构造许多不同类型的 Executor
实现的静态工厂方法:
Executors.newCachedThreadPool()
创建不限制大小线程池,但是当以- 前创建的线程可以使用时将重新使用那些线程。如果没有现有线程可用,将创建新的线
- 程并将其添加到池中。使用不到 60 秒的线程将终止并从缓存中删除。
Executors.newFixedThreadPool(int n)
创建线程池,其重新使用在不- 受限制的队列之外运行的固定线程组。在关闭前,所有线程都会因为执行过程中的失败
- 而终止,如果需要执行后续任务,将会有新的线程来代替这些线程。
Executors.newSingleThreadExecutor()
创建 Executor,其使用在不受- 限制的队列之外运行的单一工作线程,与 Swing 事件线程非常相似。保证顺序执行任务,
- 在任何给定时间,不会有多个任务处于活动状态。
class ReliableWebServer { Executor pool = Executors.newFixedThreadPool(7); public static void main(String[] args) { ServerSocket socket = new ServerSocket(80); while (true) { final Socket connection = socket.accept(); Runnable r = new Runnable() { public void run() { handleRequest(connection); } }; pool.execute(r); } } }
定制 ThreadPoolExecutor
Executors
中的newFixedThreadPool
和newCachedThreadPool
工厂方法返回的
Executor
是类ThreadPoolExecutor
的实例,是高度可定制的。
通过使用包含 ThreadFactory
变量的工厂方法或构造函数的版本,可以定义池线程的创建。
ThreadFactory
是工厂对象,其构造执行程序要使用的新线程。使用定制的线程工厂,创建
的线程可以包含有用的线程名称,并且这些线程是守护线程,属于特定线程组或具有特定优先级。
下面是线程工厂的例子,它创建守护线程,而不是创建用户线程:
public class DaemonThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); return thread; } }
java.util.concurrent
中其他类别的有用的类也是同步工具。这组类相互协作,控制一个或多个线程的执
行流。
Semaphore
、CyclicBarrier
、CountdownLatch
和Exchanger
类都是同步工具的例子。
每个类都有线程可以调用的方法,方法是否被阻塞取决于正在使用的特定同步
工具的状态和规则。