1. 创建线程池基本流程
- 选择创建方法:通过
Executors
类的静态方法来创建不同类型的线程池,这些方法会返回实现了ExecutorService
接口的线程池对象。
- 提交任务:使用返回的
ExecutorService
对象的方法(如submit
或execute
)将任务提交到线程池。
- 线程池处理任务:线程池内部的线程从任务队列中获取任务并执行。当任务执行完毕,线程可能会被复用去执行新的任务,或者在满足一定条件(如线程池关闭且线程空闲时间超过设定值)时被销毁。
2. 常见的Executors创建线程池的方法
Executors.newFixedThreadPool(int nThreads)
- 创建一个固定大小的线程池,线程池中的线程数量始终为
nThreads
。当有新任务提交时,如果线程池中有空闲线程则立即执行,否则任务会被放入队列等待,直到有线程可用。
- 示例代码:
ExecutorService executorService = Executors.newFixedThreadPool(5);
Executors.newSingleThreadExecutor()
- 创建一个单线程的线程池,只有一个线程来执行任务。所有任务按照提交的顺序依次执行,相当于顺序执行任务,避免了多线程竞争问题。
- 示例代码:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Executors.newCachedThreadPool()
- 创建一个可缓存的线程池,如果线程池中的线程在60秒内未被使用,将会被回收。当有新任务提交时,如果线程池中有空闲线程则立即执行,如果没有则创建新线程执行任务。适用于执行大量的、短期的异步任务。
- 示例代码:
ExecutorService executorService = Executors.newCachedThreadPool();
Executors.newScheduledThreadPool(int corePoolSize)
- 创建一个大小固定的线程池,支持定时及周期性执行任务。
corePoolSize
指定了线程池中的核心线程数。
- 示例代码:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
3. 任务提交到线程池执行
execute(Runnable task)
方法:用于提交不需要返回值的任务。该方法会将Runnable
类型的任务提交到线程池,线程池会安排线程执行这个任务,但不会返回任务执行结果。
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(() -> {
// 任务逻辑
System.out.println("Task is running");
});
submit(Callable<T> task)
方法:用于提交需要返回值的任务。Callable
接口的实现类的call
方法会返回一个泛型类型的结果。submit
方法会返回一个Future<T>
对象,通过这个对象可以获取任务的执行结果,也可以取消任务等操作。
ExecutorService executorService = Executors.newFixedThreadPool(5);
Future<Integer> future = executorService.submit(() -> {
// 任务逻辑,返回结果
return 10;
});
try {
Integer result = future.get();
System.out.println("Task result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}