Java异步执行方法

一.利用多线程

直接new线程

Thread t = new Thread(){
  @Override
  public void run() {
    longTimeMethod();
  }
};

使用线程池

private ExecutorService executor = Executors.newCachedThreadPool() ;

    public void fun() throws Exception {

        executor.submit(new Runnable(){

            @override

                public void run() {

                    try {
                     //要执行的业务代码,我们这里没有写方法,可以让线程休息几秒进行测试

                        Thread.sleep(10000);

                        System.out.print("睡够啦~");

                    }catch(Exception e) {

                        throw new RuntimeException("报错啦!!");

                    }

                }

        });

    }

二.采用Spring 的异步方法去执行(无返回值)

在启动类或者配置类加上 @EnableAsync 注解.

package me.deweixu.aysncdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class AysncDemoApplication {

 public static void main(String[] args) {
  SpringApplication.run(AysncDemoApplication.class, args);
 }
}

先把longTimeMethod 封装到Spring的异步方法中,这个方法一定要写在Spring管理的类中,注意注解@Async

@Async注解可以用在方法上,也可以用在类上,用在类上,对类里面所有方法起作用

@Service
public class AsynchronousService{
  @Async
  public void springAsynchronousMethod(){
    longTimeMethod();
  }
}

其他类调用这个方法。这里注意,一定要其他的类,如果在同类中调用,是不生效的。具体原因,可以去学习一下Spring AOP的原理

@Autowired
private AsynchronousService asynchronousService;

public void useAsynchronousMethod(){
  //我们需要执行的代码1
  asynchronousService.springAsynchronousMethod();
 //我们需要执行的代码2
}

三.采用Spring 的异步方法+Future接收返回值

先把longTimeMethod 封装到Spring的异步方法中,这个异步方法的返回值是Future的实例。这个方法一定要写在Spring管理的类中,注意注解@Async。

@Service
public class AsynchronousService{
  @Async
  public Future springAsynchronousMethod(){
    Integer result = longTimeMethod();
    return new AsyncResult(result);
  }
}

其他类调用这个方法。这里注意,一定要其他的类,如果在同类中调用,是不生效的。

如果调用之后接收返回值,不对返回值进行操作则为异步操作,进行操作则转为同步操作,等待对返回值操作完之后,才会继续执行主进程下面的流程

@Autowired
private AsynchronousService asynchronousService;

public void useAsynchronousMethod(){
    Future future = asynchronousService.springAsynchronousMethod();
    future.get(1000, TimeUnit.MILLISECONDS);
}

四.原生Future方法

我们需要执行的代码1

Future future = longTimeMethod2();

我们需要执行的代码2

Integer result = future.get();

可以看到,我们调用longTimeMethod2返回一个Future对象(注意了,这里的longTimeMethod2当然不是上面的longTimeMethod),然后处理“我们需要执行的代码2”,到了需要返回结果的时候直接调用future.get()便能获取到返回值。下面我们来看看longTimeMethod2如何实现。

private Future longTimeMethod2() {
  //创建线程池
  ExecutorService threadPool = Executors.newCachedThreadPool();
  //获取异步Future对象
  Future future = threadPool.submit(new Callable() {
    @Override
    public Integer call() throwsException {
        return longTimeMethod();
    }
  });
  return future;
}
<think>嗯,用户问的是Java异步执行方法,我需要详细介绍一下。首先得确定用户的基础,可能是个刚学Java的开发者,或者有一定经验想深入了解异步编程的。我需要从基础概念讲起,然后逐步深入不同的实现方式。 首先,异步执行是什么?简单来说就是不阻塞主线程,让任务在后台执行,完成后处理结果。这对提高应用性能,特别是IO密集型或高并发场景很重要。用户可能想知道为什么需要异步,以及如何实现。 接下来,得考虑Java中实现异步的不同方法。传统的Thread和Runnable是最基本的,但可能不够高效,因为线程创建和管理的开销大。然后ExecutorService线程池,这个更高效,可以复用线程。这里需要举例说明,比如使用ExecutorService提交任务。 然后是Future和Callable,它们能获取异步任务的结果,但Future.get()会阻塞,可能不是最佳选择。接着是CompletableFuture,这是Java 8引入的,支持链式调用和组合多个异步任务,功能强大。比如thenApply、thenAccept等方法,可以处理结果或异常。 还有Spring的@Async注解,这在Spring应用中很方便,但需要配置线程池和开启异步支持。可能用户是在用Spring框架,所以这个点很重要。要提到如何在Spring Boot中启用@Async,以及自定义线程池的方法。 响应式编程如Reactor或RxJava,虽然属于高级话题,但用户可能想了解更现代的解决方案。可以简要提一下,但重点还是放在Java原生和Spring的支持上。 需要注意的点:异步的异常处理,比如CompletableFuture的exceptionally方法;线程池的配置参数,如核心线程数、队列类型等,避免资源耗尽;以及异步适用的场景,比如不适合CPU密集型任务,可能反而降低性能。 用户可能的应用场景,比如Web服务器处理请求,需要异步执行数据库操作或调用外部API,提高吞吐量。或者后台任务如发送邮件、生成报告,不影响主流程。 可能用户没问但需要提醒的是,异步带来的复杂性,比如回调地狱,这时候CompletableFuture或响应式编程能帮助管理。还有线程安全问题,异步代码中共享变量需要注意同步机制。 总结时,要分点列出各种方法,优缺点和适用场景,让用户能根据需求选择。确保语言通俗易懂,代码示例正确,比如用Thread、ExecutorService、CompletableFuture和@Async的例子,帮助用户理解。</think>在 Java 中实现异步执行可显著提升程序性能,特别是在处理 I/O 操作或高并发场景时。以下是主要实现方法及详细说明: --- ### 一、基础线程方式 #### 1. Thread 类 ```java new Thread(() -> { // 异步任务代码 System.out.println("异步执行"); }).start(); ``` - **优点**:简单直观 - **缺点**:频繁创建线程开销大,难以管理 #### 2. Runnable + ExecutorService ```java ExecutorService executor = Executors.newFixedThreadPool(4); executor.submit(() -> { // 异步任务 return "结果"; }); executor.shutdown(); // 需显式关闭 ``` - **推荐线程池类型**: - `newCachedThreadPool()` 弹性线程池 - `newScheduledThreadPool()` 定时任务 --- ### 二、Future 机制 ```java ExecutorService executor = Executors.newFixedThreadPool(2); Future<String> future = executor.submit(() -> { Thread.sleep(1000); return "操作结果"; }); // 阻塞获取结果 String result = future.get(); ``` - **缺点**:`get()` 方法会导致调用线程阻塞 --- ### 三、CompletableFuture (Java 8+) #### 1. 基础使用 ```java CompletableFuture.supplyAsync(() -> { // 异步计算 return 42; }).thenAccept(result -> { System.out.println("处理结果:" + result); }); ``` #### 2. 链式调用 ```java CompletableFuture.supplyAsync(() -> "数据") .thenApplyAsync(s -> s + "加工") .thenAcceptBoth( CompletableFuture.supplyAsync(() -> "补充数据"), (r1, r2) -> System.out.println(r1 + " | " + r2) ); ``` #### 3. 异常处理 ```java CompletableFuture.supplyAsync(() -> { if (error) throw new RuntimeException(); return "正常"; }).exceptionally(ex -> { System.out.println("错误处理: " + ex.getMessage()); return "默认值"; }); ``` --- ### 四、Spring 的 @Async 注解 #### 1. 启用异步 ```java @SpringBootApplication @EnableAsync public class App { ... } ``` #### 2. 定义异步方法 ```java @Service public class MyService { @Async public CompletableFuture<String> asyncMethod() { return CompletableFuture.completedFuture("结果"); } } ``` #### 3. 自定义线程池 ```java @Configuration public class AsyncConfig { @Bean("customPool") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); executor.initialize(); return executor; } } // 使用指定线程池 @Async("customPool") public void customAsync() { ... } ``` --- ### 五、响应式编程(Reactor/RxJava) ```java // Reactor 示例 Mono.fromCallable(() -> { return longTimeOperation(); }).subscribeOn(Schedulers.boundedElastic()) .subscribe(result -> { System.out.println("处理结果: " + result); }); ``` --- ### 关键注意事项 1. **线程池配置**: - 根据任务类型选择线程池类型 - 设置合理的队列容量和拒绝策略 2. **资源泄漏**: - 确保正确关闭线程池 - 使用 try-with-resources 管理资源 3. **上下文传递**: - 异步时注意 ThreadLocal 数据丢失问题 - 使用 `TransmittableThreadLocal`(阿里开源库)解决 4. **性能监控**: - 通过 JMX 或 Micrometer 监控线程池状态 --- ### 应用场景对比 | 场景 | 推荐方案 | |----------------------|-----------------------------| | 简单异步任务 | CompletableFuture | | Spring 项目 | @Async + 线程池配置 | | 复杂流水线处理 | Reactor/RxJava 响应式编程 | | 定时/延迟任务 | ScheduledExecutorService | 建议根据项目需求和Java版本选择合适方案,新项目推荐优先使用CompletableFuture和响应式编程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值