Skip to content

下面是根据你提供的代码,为你总结的异步任务添加和管理的笔记:

异步任务管理:使用 @AsyncExecutorService

在 Java 中,异步任务的处理可以极大提高应用程序的性能,特别是在需要进行 IO 密集型操作(例如数据库查询、API 调用等)时。Spring 提供了 @Async 注解来支持异步执行,但有时我们可能需要使用更灵活的线程池和控制方式,像你代码中的 ExecutorService 就是一个很好的示例。

异步任务的基本步骤:

  1. 标记异步方法: 使用 @Async 注解标记一个方法为异步执行的方法。这样,方法就会在另一个线程中执行,而不会阻塞主线程。异步方法可以返回 FutureCompletableFuturevoid(不需要返回值)。

    java
    @Async
    public void newsEventStock(int category) {
        // 异步方法的逻辑
    }
  2. 创建线程池: 在上面的代码中,ExecutorService 是用来管理异步任务的线程池。你使用了 Executors.newFixedThreadPool(summaryPoolSize) 来创建一个固定大小的线程池,确保同时有 summaryPoolSize 个线程处理异步任务。

    java
    ExecutorService asyncExecutor = Executors.newFixedThreadPool(summaryPoolSize);

    你可以通过 ExecutorService 来管理线程池的生命周期和控制并发数。

  3. 跟踪任务进度: 为了能够追踪异步任务的进度,代码中使用了 ProgressTracker 类来跟踪任务的进度。每当一个任务完成时,调用 tracker.increment() 方法更新进度。

    java
    ProgressTracker tracker = new ProgressTracker(totalTasks, "资讯", asyncExecutor);
    tracker.start();

    这种方式可以让你在所有异步任务完成后,得到一个明确的进度反馈。

  4. 使用 CompletableFuture 管理异步任务CompletableFuture 是一种更灵活的异步执行模型,允许你非阻塞地执行异步操作,并且可以通过 then 方法连接多个操作。

    在代码中,CompletableFuture.runAsync 被用来执行每个异步任务。每个任务执行完后,它会执行 tracker.increment() 来更新进度,并且处理数据库插入、API 调用等逻辑。

    java
    List<CompletableFuture<Void>> futures = stocks.stream()
            .map(stock -> CompletableFuture.runAsync(() -> {
                // 异步执行的任务逻辑
            }, asyncExecutor))
            .toList();

    这里的 futures 是一个 CompletableFuture 对象的列表,它代表每个异步任务。你可以通过 CompletableFuture.allOf() 方法等待所有异步任务完成。

  5. 等待所有任务完成: 通过 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(),等待所有异步任务完成。join() 方法会阻塞当前线程直到所有任务执行完毕。

    java
    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

代码解析:

  1. 开始异步任务: 在 newsEventStock 方法开始时,通过调用 stockData.listStockFromCache() 获取所有股票的列表,并计算出任务总数。

  2. 创建线程池和进度追踪器: 使用固定大小的线程池 asyncExecutor 来控制并发任务数,并通过 ProgressTracker 追踪任务进度。

  3. 异步执行每个任务: 使用 Java 8 的 stream()map() 来异步执行每个股票的处理任务。每个股票会被传入一个 CompletableFuture.runAsync() 方法中,并在该任务中执行 API 请求、数据库插入等操作。

  4. 更新任务状态: 每个任务完成时,会更新进度追踪器的进度,确保所有任务的执行进度被正确记录。

  5. 等待所有任务完成CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join() 会等待所有异步任务完成。join() 方法会确保方法只有在所有异步操作完成后才返回。

总结:

  • 异步执行任务: 使用 @AsyncCompletableFuture 来并行执行耗时操作,可以大大提高系统的响应速度和吞吐量。
  • 线程池管理: 通过 ExecutorService 来管理线程池,可以控制并发任务数,并且避免创建过多线程造成系统资源压力。
  • 任务进度追踪: 使用 ProgressTracker 来跟踪异步任务的执行进度,帮助开发者了解任务执行的情况。
  • 等待任务完成: 使用 CompletableFuture.allOf() 等方法来等待所有异步任务执行完成,从而在所有任务完成后进行后续操作。

优化建议:

  1. 线程池的配置:确保 summaryPoolSize 的大小与服务器的硬件资源(如 CPU 核数)相匹配,避免创建过多线程导致线程上下文切换过于频繁,影响性能。
  2. 异常处理:你已经很好地处理了异常,但可以考虑使用 CompletableFuture.exceptionally() 方法处理任务中的异常,这样可以确保任务的失败不会影响其他任务的执行。
  3. 资源回收:如果不再使用 ExecutorService,应该确保在适当的时机关闭线程池,以避免资源泄露。可以使用 asyncExecutor.shutdown() 来优雅地关闭线程池。

✨ 网站运行时间: 3年11月15天 ❤️ 道阻且长,行则将至 - 微信号: heikedreamer