SpringBoot中异步请求的使用

作用:可以先释放请求线程的资源,提高系统的吞吐量

AsyncContext asyncContext = request.startAsync();   // 创建一个异步上下文对象
asyncContext.addListener(new AsyncListener() {   //设置监听器:可设置其开始、完成、异常、超时等事件的回调处理
    @Override
    public void onTimeout(AsyncEvent event) throws IOException {
        System.out.println("超时了...");
    }
    @Override
    public void onStartAsync(AsyncEvent event) throws IOException {
        System.out.println("线程开始");
    }
    @Override
    public void onError(AsyncEvent event) throws IOException {
        System.out.println("发生错误:"+event.getThrowable());
    }
    @Override
    public void onComplete(AsyncEvent event) throws IOException {
        System.out.println("执行完成");
    }
});
asyncContext.setTimeout(20000);   //设置超时时间
asyncContext.start(new Runnable() {
    public void run() {
        try {
            Thread.sleep(10000);
            System.out.println("内部线程:" + Thread.currentThread().getName());
            asyncContext.getResponse().setCharacterEncoding("utf-8");
            asyncContext.getResponse().setContentType("text/html;charset=UTF-8");
            asyncContext.getResponse().getWriter().println("这是异步的请求返回");   //异步请求完成通知
        } catch (Exception e) {
            System.out.println("异常:"+e);
        }
        asyncContext.complete();  //此时整个请求才完成
    }
});
//此时之类 request的线程连接已经释放了
System.out.println("主线程:" + Thread.currentThread().getName());

 

创建一个异步请求的上下文对象(AsyncContextImpl),存储request  response  设置回调,超时时间等

AsyncContextImpl启动了一个异步的runnable ,这个runnable对象,是在 processor.getExecutor().execute(runnable)启动

asyncStateMachine 异步sevlet使用了状态机的形式  后续有时间继续查看源码

当然,请求线程可以提前结束。

 

### 启动和处理异步请求 在Spring Boot中,通过简单的配置可以轻松实现异步请求的支持。为了使一个方法成为异步执行的方法,在其定义前加上`@Async`注解即可[^3]。 对于启动类或任意配置类而言,需添加`@EnableAsync`注解以便开启异步支持: ```java @EnableAsync @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 当希望某个服务中的特定方法作为异步方法运行时,则应在该方法声明处应用`@Async`注解,并确保此方法返回类型为`void`或是`Future<?>`。下面是一个例子展示如何创建这样的异步方法: ```java @Service public class AsyncService { @Async public Future<String> asyncMethodWithReturnType() throws InterruptedException { long duration = (long)(Math.random()*5000); System.out.println("asyncMethodWithReturnType(), threadName="+Thread.currentThread().getName()+", start"); Thread.sleep(duration); System.out.println("asyncMethodWithReturnType(), threadName="+Thread.currentThread().getName()+", end"); return new AsyncResult<>("hello"+duration); } @Async public void simpleAsyncMethod(){ try{ long duration=(long)(Math.random()*5000); System.out.println("simpleAsyncMethod(), threadName="+Thread.currentThread().getName()+", start"); Thread.sleep(duration); System.out.println("simpleAsyncMethod(), threadName="+Thread.currentThread().getName()+", end"); }catch(InterruptedException e){ e.printStackTrace(); } } } ``` 值得注意的是,默认情况下,所有的异步操作都会被分配到由Spring管理的一个默认线程池内执行;然而,也可以自定义线程池来更好地控制并发行为以及资源利用效率等问题[^1]。 #### 自定义线程池设置 如果想要更精细地调整用于执行异步任务的线程池参数,可以通过重写`concurrent`包下的`TaskExecutor` bean来进行定制化配置: ```java @Configuration public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(7); executor.setMaxPoolSize(42); executor.setQueueCapacity(11); executor.initialize(); return executor; } @Override publicAdvice getAsyncUncaughtExceptionHandler() { return null; // 可选:提供异常处理器逻辑 } } ``` 上述代码片段展示了如何覆盖默认的任务执行器并指定核心线程数、最大线程数量及队列容量等属性值,从而满足不同应用场景下对性能的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值