异步调用的接口设计

简介: 异步调用的接口设计

何谓异步?

每次调用都创建一个新的线程去执行, 不会等待上一次调用执行完,再执行下一个请求

SpringBoot项目怎么做

  1. 在启动类上添加:@EnableAsync 注解
  2. 项目中添加下面两个类
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import com.imooc.miaoshaproject.util.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
 * 线程池配置
 **/
@Configuration
public class ThreadPoolConfig
{
    // 核心线程池大小
    private int corePoolSize = 50;
    // 最大可创建的线程数
    private int maxPoolSize = 200;
    // 队列最大长度
    private int queueCapacity = 1000;
    // 线程池维护线程所允许的空闲时间
    private int keepAliveSeconds = 300;
    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor()
    {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(maxPoolSize);
        executor.setCorePoolSize(corePoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
    /**
     * 执行周期性或定时任务
     */
    @Bean(name = "scheduledExecutorService")
    protected ScheduledExecutorService scheduledExecutorService()
    {
        return new ScheduledThreadPoolExecutor(corePoolSize,
                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
        {
            @Override
            protected void afterExecute(Runnable r, Throwable t)
            {
                super.afterExecute(r, t);
                Threads.printException(r, t);
            }
        };
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
/**
 * 线程相关工具类.
 *
 */
public class Threads
{
    private static final Logger logger = LoggerFactory.getLogger(Threads.class);
    /**
     * sleep等待,单位为毫秒
     */
    public static void sleep(long milliseconds)
    {
        try
        {
            Thread.sleep(milliseconds);
        }
        catch (InterruptedException e)
        {
            return;
        }
    }
    /**
     * 停止线程池
     * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
     * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
     * 如果仍人超時,則強制退出.
     * 另对在shutdown时线程本身被调用中断做了处理.
     */
    public static void shutdownAndAwaitTermination(ExecutorService pool)
    {
        if (pool != null && !pool.isShutdown())
        {
            pool.shutdown();
            try
            {
                if (!pool.awaitTermination(120, TimeUnit.SECONDS))
                {
                    pool.shutdownNow();
                    if (!pool.awaitTermination(120, TimeUnit.SECONDS))
                    {
                        logger.info("Pool did not terminate");
                    }
                }
            }
            catch (InterruptedException ie)
            {
                pool.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
    
    /**
     * 打印线程异常信息
     */
    public static void printException(Runnable r, Throwable t)
    {
        if (t == null && r instanceof Future<?>)
        {
            try
            {
                Future<?> future = (Future<?>) r;
                if (future.isDone())
                {
                    future.get();
                }
            }
            catch (CancellationException ce)
            {
                t = ce;
            }
            catch (ExecutionException ee)
            {
                t = ee.getCause();
            }
            catch (InterruptedException ie)
            {
                Thread.currentThread().interrupt();
            }
        }
        if (t != null)
        {
            logger.error(t.getMessage(), t);
        }
    }
}
  1. 在需要异步调用的接口上添加@Async(“threadPoolTaskExecutor”)注解即可
@Async("threadPoolTaskExecutor")
    @RequestMapping(value = "/test",method = {RequestMethod.GET,RequestMethod.POST})
    @ResponseBody
    public void test() {
        System.out.println("===test===");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
目录
相关文章
|
27天前
|
消息中间件 数据库
开发指南062-异步处理接口
后台有些接口耗时非常长,如果采用同步处理机制,前台等待时间过长,这时需要改异步操作
|
6月前
接口幂等性设计
接口幂等性设计
71 1
|
JavaScript API
接口封装如何实现?
接口封装如何实现?
|
3月前
|
缓存 NoSQL Java
接口幂等该如何设计和实现
本文探讨了程序开发中常见的重复操作问题,如多次点击生成多余订单或支付、RPC调用失败后的重试机制滥用及非法重复请求等。通过接口幂等性设计可有效解决这类问题,确保相同请求多次执行结果一致无副作用。文章详细解释了幂等性的概念及其重要性,并提供了具体的设计与实现方法,包括使用唯一标识符、设计幂等操作、事务处理及缓存策略。此外,还讨论了实现幂等性接口所带来的好处,如并发请求处理、失败请求管理及系统集成等,并提出了验证接口幂等性的策略。通过这些技术和方法的应用,可以显著提升系统的稳定性和用户体验。
|
5月前
|
JSON 程序员 数据格式
程序员必知:同步接口和异步接口
程序员必知:同步接口和异步接口
383 0
|
6月前
|
存储 缓存 数据库
接口幂等有哪些实现方式
接口幂等有哪些实现方式
43 0
|
6月前
|
测试技术
封装并集中处理业务逻辑
封装并集中处理业务逻辑
42 1
|
前端开发 Java Spring
SpringMVC 如何实现异步处理及内置异步请求类介绍
SpringMVC 如何实现异步处理及内置异步请求类介绍
115 1
|
存储 设计模式 Java
Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发(上)
Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发
205 0