Java 和 Guava 中的线程池
1、概览 本文将带你了解 Java 中的线程池。首先介绍 Java 中的标准库,然后介绍 Google 的 Guava 库。
2、线程池 在 Java 中,线程被映射到系统级线程,而系统级线程是操作系统的资源。如果不加控制地创建线程,这些资源可能很快就会耗尽。
操作系统也会在线程之间进行上下文切换,以模拟并行处理。一个简单的观点是,创建的线程越多,每个线程实际工作的时间就越少。
线程池模式有助于在多线程应用中节省资源,并将并行性控制在某些预定义的范围内。
使用线程池时,我们将并发代码编写为并行任务的形式,并将它们提交给线程池实例执行。这个实例控制着多个可重复使用的线程来执行这些任务。
该模式允许我们控制应用创建的线程数量及其生命周期。还能调度任务的执行,并将接收到的任务保存在队列中。
3、Java 中的线程池 3.1、Executors、Executor 和 ExecutorService Executors 工具类包含多个用于创建预配置线程池实例的方法。这些类是一个很好的起点。如果不需要进行任何自定义微调,就可以使用它们。
在 Java 中,我们使用 Executor 和 ExecutorService 接口来处理不同的线程池实现。通常,应该使代码与线程池的实际实现解耦,并在整个应用中使用这些接口。
3.1.1、Executor Executor 接口有一个 execute 方法,用于提交实现了 Runnable 接口的实例以供执行。
来看一个快速示例,演示如何使用 Executors API 获取由单线程池和无界队列支持的 Executor 实例,以便按顺序执行任务。
如下,运行一个任务,只需在屏幕上打印 “Hello World” 即可。我们以 lambda(Java 8 的一个特性)的形式提交任务,它被推断为 Runnable:
Executor executor = Executors.newSingleThreadExecutor(); executor.execute(() -> System.out.println("Hello World")); 3.1.2、ExecutorService ExecutorService 接口包含大量用于控制任务进度和管理服务终止的方法。使用该接口,我们可以提交任务以供执行,还可以使用返回的 Future 实例控制任务的执行。
现在,创建一个 ExecutorService,提交一项任务,然后使用返回的 Future 的 get 方法等待提交的任务完成并返回结果值: