Java中Executor的使用方法

发布时间:2021-07-13 09:21:59 作者:chen
来源:亿速云 阅读:122
# Java中Executor的使用方法

## 一、Executor框架概述

Java中的Executor框架是Java 5引入的一套线程管理机制,它提供了一种将任务提交与任务执行分离的机制。通过Executor,开发者可以专注于任务逻辑的编写,而无需手动管理线程的创建和生命周期。

### 1.1 为什么需要Executor
- 传统线程创建方式(直接new Thread)存在资源消耗大、难以管理的问题
- Executor提供了线程池功能,实现线程复用
- 统一的任务提交接口,简化并发编程

### 1.2 核心接口关系

Executor ├── ExecutorService │ ├── ScheduledExecutorService │ └── AbstractExecutorService └── ThreadPoolExecutor


## 二、基本使用方法

### 2.1 创建ExecutorService

```java
// 创建固定大小的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);

// 创建单线程的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

// 创建可缓存的线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

2.2 提交任务

// 执行Runnable任务
executor.execute(() -> {
    System.out.println("执行任务");
});

// 提交Callable任务并获取Future
Future<String> future = executor.submit(() -> {
    Thread.sleep(1000);
    return "任务结果";
});

2.3 关闭ExecutorService

// 平缓关闭,不再接受新任务,等待已提交任务完成
executor.shutdown();

// 立即关闭,尝试中断正在执行的任务
executor.shutdownNow();

三、线程池配置详解

3.1 ThreadPoolExecutor核心参数

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    int corePoolSize,      // 核心线程数
    int maximumPoolSize,  // 最大线程数
    long keepAliveTime,   // 空闲线程存活时间
    TimeUnit unit,        // 时间单位
    BlockingQueue<Runnable> workQueue, // 工作队列
    ThreadFactory threadFactory,       // 线程工厂
    RejectedExecutionHandler handler   // 拒绝策略
);

3.2 工作队列类型

队列类型 特点
ArrayBlockingQueue 有界队列,FIFO
LinkedBlockingQueue 无界队列(默认),FIFO
SynchronousQueue 不存储元素的阻塞队列
PriorityBlockingQueue 具有优先级的无界队列

3.3 拒绝策略

策略类 行为
AbortPolicy 直接抛出RejectedExecutionException
CallerRunsPolicy 由调用线程执行该任务
DiscardPolicy 直接丢弃任务
DiscardOldestPolicy 丢弃队列中最旧的任务

四、高级功能使用

4.1 ScheduledExecutorService

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);

// 延迟执行
scheduler.schedule(() -> {
    System.out.println("延迟3秒执行");
}, 3, TimeUnit.SECONDS);

// 固定频率执行
scheduler.scheduleAtFixedRate(() -> {
    System.out.println("每2秒执行一次");
}, 1, 2, TimeUnit.SECONDS);

4.2 Future与异步结果处理

ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> future = executor.submit(() -> {
    Thread.sleep(1000);
    return 42;
});

// 获取结果(阻塞)
try {
    Integer result = future.get();
    System.out.println("结果: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

4.3 CompletionService

ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<String> completionService = new ExecutorCompletionService<>(executor);

// 提交多个任务
completionService.submit(() -> "任务1");
completionService.submit(() -> "任务2");

// 获取已完成的任务结果
for (int i = 0; i < 2; i++) {
    Future<String> completedFuture = completionService.take();
    System.out.println(completedFuture.get());
}

五、最佳实践与注意事项

5.1 线程池大小设置

5.2 资源清理

executor.shutdown();
try {
    if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
        executor.shutdownNow();
    }
} catch (InterruptedException e) {
    executor.shutdownNow();
    Thread.currentThread().interrupt();
}

5.3 常见问题

  1. 避免无界队列导致OOM
  2. 正确处理线程池中抛出的异常
  3. 注意线程上下文切换开销

六、总结

Java的Executor框架为并发编程提供了强大而灵活的工具。通过合理配置线程池参数、选择合适的队列和拒绝策略,可以构建高效稳定的并发系统。掌握Executor的使用方法,能够显著提升Java应用的并发处理能力和资源利用率。

注意:实际项目中建议使用ThreadPoolExecutor构造函数创建线程池,而不是Executors工厂方法,以便更精确地控制线程池行为。 “`

推荐阅读:
  1. executor启动task
  2. Java并发框架Executor API的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:如何解决iOS11中断点续传的bug

下一篇:iOS11不能定位怎么办

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》