Java线程池的用法(附带示例)
当系统中存在大量并发线程,且每个线程仅执行短暂任务时,频繁创建和销毁线程会显著降低系统效率。这是因为线程的创建和销毁过程本身消耗时间。
是否存在一种机制,能够使线程被重复利用呢?也就是说,线程在完成一个任务后,不立即销毁,而是继续执行其他任务。解决方案是预先创建一组线程,并将它们存储在所谓的线程池中。
当需要执行任务时,可以直接从线程池中获取线程,任务完成后,线程被归还到线程池中,从而避免了频繁创建和销毁过程,实现了对线程的复用。这与生活中的公共交通工具模式类似。
线程池如下图所示:

图 1 线程池
线程池具有以下优点:
【实例 1】创建线程池并利用线程池,代码如下:
是否存在一种机制,能够使线程被重复利用呢?也就是说,线程在完成一个任务后,不立即销毁,而是继续执行其他任务。解决方案是预先创建一组线程,并将它们存储在所谓的线程池中。
当需要执行任务时,可以直接从线程池中获取线程,任务完成后,线程被归还到线程池中,从而避免了频繁创建和销毁过程,实现了对线程的复用。这与生活中的公共交通工具模式类似。
线程池如下图所示:

图 1 线程池
线程池具有以下优点:
- 提高响应速度(减少创建新线程的时间);
- 降低资源消耗(重复利用线程池中的线程,不需要每次都创建线程);
- 便于线程管理。
线程池相关API
在 JDK 5.0 之前,我们必须手动自定义线程池。从 JDK 5.0 开始,Java 内置了与线程池相关的 API。java.util.concurrent 包中提供与线程池相关的 API——ExecutorService 和 Executors。1) ExecutorService
ExecutorService 是真正的线程池接口,常见子类为 ThreadPoolExecutor:- void execute(Runnable command):执行任务/命令,没有返回值,一般用来执行 Runnable;
- <T> Future<T> submit(Callable<T> task):执行任务,有返回值,一般用来执行 Callable;
- void shutdown():关闭连接池。
2) Executors
Executors 是一个线程池的工厂类,通过此类的静态工厂方法可以创建多种类型的线程池对象:- Executors.newCachedThreadPool():创建一个可以根据需要创建新线程的线程池。
- Executors.newFixedThreadPool(int nThreads):创建一个可以重用固定线程数的线程池。
- Executors.newSingleThreadExecutor():创建一个只有一个线程的线程池。
- Executors.newScheduledThreadPool(int corePoolSize):创建一个线程池,它可以在给定的延迟时间后运行命令或定期运行命令。
【实例 1】创建线程池并利用线程池,代码如下:
public class NumberThread implements Runnable {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
}
public class NumberThread02 implements Runnable {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (i % 2 != 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
}
import java.util.concurrent.Callable;
public class NumberThread03 implements Callable {
@Override
public Object call() throws Exception {
int evenSum = 0; // 记录偶数的和
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
evenSum += i;
}
}
return evenSum;
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class ThreadPoolTest {
public static void main(String[] args) {
// 1.提供指定线程数量的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
// 设置线程池的属性
System.out.println(service.getClass()); // ThreadPoolExecutor
service1.setMaximumPoolSize(50); // 设置线程池中线程数的上限
// 2.执行指定线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
service.execute(new NumberThread()); // 适用于Runnable
service.execute(new NumberThread02()); // 适用于Runnable
try {
Future future = service.submit(new NumberThread03()); // 适用于Callable
System.out.println("总和为:" + future.get());
} catch (Exception e) {
e.printStackTrace();
}
// 3.关闭连接池
service.shutdown();
}
}
在上述代码中,我们构建了一个线程池,并在 NumberThread03 类中通过实现 Callable 接口采用了 JDK 5.0 引入的一种新型线程创建方式。submit() 方法适用于通过 Callable 接口创建的线程。
ICP备案:
公安联网备案: