异步调用的接口设计

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

何谓异步?

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

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();
        }
    }
目录
相关文章
|
30天前
接口幂等性设计
接口幂等性设计
24 1
|
1月前
|
测试技术
封装并集中处理业务逻辑
封装并集中处理业务逻辑
12 1
|
9月前
|
存储 搜索推荐 API
如何设计 RPC 接口
如何设计 RPC 接口
178 0
|
10月前
|
存储 设计模式 Java
Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发(上)
Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发
126 0
|
10月前
|
设计模式 Java 数据库连接
Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发(下)
Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发
183 0
|
10月前
|
测试技术 数据处理 数据安全/隐私保护
接口自动化测试中一些复杂请求的处理方式
接口自动化用例编写中,遇到复杂的请求数据,该如何处理?
|
10月前
|
SQL 负载均衡 Java
怎么设计一个高质量的接口API设计
什么是幂等性?对于同一笔业务交易,不管调用多少次,只会成功处理一次。二、幂等性设计我们转账业务为例,来说明一下这个问题,转账接口一定要做到幂等性,否则会出现重复转账的问题。调用转账接口从A中转100元资金给B,参数中会携带业务流水号biz_no和源账户A,目的账户B,和转账金额100,业务流水号biz_no是唯一的。转账接口实现有以下实现方式。
|
Java 开发者
异步调用|学习笔记
快速学习异步调用
55 0
异步调用|学习笔记
|
安全 前端开发 物联网
接口设计篇《怎么设计好的接口?》
这样设计接口【升职加薪】?
357 0