欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 工作中使用线程池

工作中使用线程池

2025/9/23 15:24:52 来源:https://blog.csdn.net/m0_64289188/article/details/140390967  浏览:    关键词:工作中使用线程池

文章目录

    • 概要
    • 直接创建线程的缺点
    • 使用线程池的优势
    • 创建线程池给 Spring 管理---示例
      • 创建线程池配置类
      • 使用线程池
      • 启用异步支持
      • 创建控制器调用服务
      • 运行应用
      • 总结
    • Future介绍
      • `Future` 接口的主要方法
      • 示例代码
    • `CompletableFuture`
      • `CompletableFuture` 示例
      • 总结

概要

使用线程池的过程中,直接使用 new 关键字来创建线程(例如 new Thread())是不推荐的做法。这是因为直接创建线程的方式存在一些缺点,而通过线程池可以更有效地管理线程资源,提升应用程序的性能和稳定性。

直接创建线程的缺点

a. 资源消耗大

每次创建一个新线程都需要分配系统资源,尤其是内存资源。频繁创建和销毁线程会导致系统资源的浪费,并可能引起性能问题

b. 线程管理困难

直接创建的线程在使用完之后需要手动管理其生命周期。如果没有正确地管理,可能会导致线程泄漏或其他问题,例如过多的线程占用系统资源。

c. 难以控制并发数量

如果不加控制地创建线程,系统可能会因为过多的并发线程而陷入崩溃状态。线程数的增加会导致上下文切换的开销增大,从而影响系统性能。

使用线程池的优势

a. 资源复用

线程池在初始化时会创建一定数量的线程,这些线程可以复用,而不需要每次都创建新的线程,从而减少了资源消耗。

b. 简化线程管理

线程池会自动管理线程的生命周期,开发者只需要提交任务即可,不需要关心线程的创建和销毁,减少了代码复杂度和错误率。

c. 控制并发数量

线程池可以通过配置最大线程数来控制并发线程的数量,避免了系统因为线程过多而崩溃的问题。

创建线程池给 Spring 管理—示例

以下是一个在工作中常用的、由Spring管理的线程池配置和使用的完整案例。这段代码展示了如何在Spring Boot应用中创建和配置线程池,并使用它来执行异步任务。

创建线程池配置类

通过创建一个配置类来定义线程池:

@Configuration
public class ThreadPoolConfig {/*** 定义一个名为 "taskExecutor" 的线程池Bean*/@Bean(name = "taskExecutor")public Executor taskExecutor() {// 创建ThreadPoolTaskExecutor实例ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 设置核心线程数,即线程池在闲置状态下的最小线程数executor.setCorePoolSize(5);// 设置最大线程数,即线程池在繁忙状态下的最大线程数executor.setMaxPoolSize(10);// 设置队列容量,当有超过核心线程数的任务提交时,这些任务会被放在队列中等待执行executor.setQueueCapacity(25);// 设置线程名前缀,方便在日志和监控中区分线程池中的线程executor.setThreadNamePrefix("MyThreadPool-");// 初始化线程池executor.initialize();// 返回配置好的线程池实例return executor;}
}

使用线程池

在Spring Bean中注入线程池并使用它来执行任务:

@Service
public class MyService {//@Async("taskExecutor"):这个注解表示该方法将在异步执行。//"taskExecutor"是我们定义的线程池名称,这意味着这个方法将由taskExecutor线程池中的线程来执行,而不是由调用线程执行。//这个机制允许任务在后台执行,从而不会阻塞调用者的线程。@Async("taskExecutor")public CompletableFuture<String> executeTask(String taskName) {System.out.println(Thread.currentThread().getName() + " - Executing task: " + taskName);// 模拟任务处理try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return CompletableFuture.completedFuture("Task " + taskName + " completed");}
}

启用异步支持

在Spring配置类中启用异步方法调用:

@Configuration
@EnableAsync
public class AsyncConfig {
}

创建控制器调用服务

在控制器中调用服务方法来执行任务:

@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/execute")public String executeTask(@RequestParam String taskName) {CompletableFuture<String> future = myService.executeTask(taskName);return "Task " + taskName + " is being executed.";}
}

运行应用

确保你的Spring Boot应用程序可以正常运行。启动应用后,你可以通过访问以下URL来测试线程池:

http://localhost:8080/execute?taskName=test

总结

通过上述步骤,你可以在Spring Boot应用中创建和使用线程池,并将其配置成由Spring管理。这样可以方便地管理并发任务,提高应用的性能和响应能力。

Future介绍

Future 是 Java 中用于表示异步计算结果的接口。它的主要功能是允许你在任务还未完成时获取结果,而不是阻塞等待任务完成。Future 提供了一些方法来检查任务是否完成、等待任务完成并获取结果,以及取消任务等。

Future 接口的主要方法

Future 接口在 java.util.concurrent 包中定义,包含以下主要方法:

  • boolean cancel(boolean mayInterruptIfRunning):尝试取消任务。如果任务已经完成或已经被取消,则返回 false;如果任务成功取消,则返回 true
  • boolean isCancelled():如果任务在完成前被取消,则返回 true
  • boolean isDone():如果任务已完成,则返回 true
  • V get():等待任务完成并获取结果,如果任务未完成,则阻塞直到任务完成。
  • V get(long timeout, TimeUnit unit):等待任务完成并获取结果,但只等待指定的时间。如果在超时时间内任务未完成,则抛出 TimeoutException

示例代码

public class FutureTest {public static void main(String[] args) {// 创建线程池ExecutorService executor = Executors.newFixedThreadPool(2);// 提交任务Future<Integer> future = executor.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {// 模拟长时间任务Thread.sleep(2000);return 123456;}});// 检查任务是否完成if (!future.isDone()) {System.out.println("Task is not completed ...");}// 获取任务结果try {Integer result = future.get(); // 这将阻塞直到任务完成System.out.println("Task completed!! Result: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}// 关闭线程池executor.shutdown();}
}

CompletableFuture

CompletableFuture 是 Java 8 引入的一个更高级的类,它实现了 Future 接口,并提供了更多功能,如流式处理和组合多个异步任务。CompletableFuture 允许更灵活的方式来处理异步计算,支持非阻塞、回调、异常处理等。

CompletableFuture 示例

public class CompletableFutureTest {public static void main(String[] args) {// 创建一个CompletableFutureCompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {// 模拟长时间任务try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return 123321;});// 添加回调future.thenAccept(result -> System.out.println("Task completed!! Result: " + result));// 等待任务完成try {future.get(); // 阻塞等待} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}
}
  • runAsync 适用于没有返回值的任务,返回 CompletableFuture。
CompletableFuture.runAsync(()->function());
  • supplyAsync 适用于有返回值的任务,返回 CompletableFuture,其中 T 是任务返回的结果类型。

总结

  • Future 接口用于表示异步计算的结果,可以检查任务是否完成、获取结果或取消任务。
  • CompletableFutureFuture 的扩展,提供了更丰富的功能,如流式处理、组合多个异步任务、处理异常等。它更适合于现在Java应用中处理异步任务。

❤觉得有用的可以留个关注~~❤

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词