zoukankan      html  css  js  c++  java
  • SpringBoot基于注解@Async使用线程的异步调用

    @Async简介:   在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

    @Async用法:   @Async添加到方法上

    话不多说,代码如下

    1.SpringBoot 配置线程池

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    import java.util.concurrent.Executor;
    import java.util.concurrent.ThreadPoolExecutor;
    
    @Configuration
    @EnableAsync
    public class ExecutorConfig {
        private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);
        private int CORE_POOL_SIZE = 5;//线程核心数
        private int MAX_POOL_SIZE = 200;//最大线程数
        private int QUERE_CAPACITY = 99999;//队列大小
        private String THREAD_NAME_PREFIX = "demo_thead_pool_";//给线程池分组,组名
    
        @Bean
        public Executor asyncServiceExecutor() {
            logger.info("start asyncServiceExecutor");
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            //配置核心线程数
            executor.setCorePoolSize(CORE_POOL_SIZE);
            //配置最大线程数
            executor.setMaxPoolSize(MAX_POOL_SIZE);
            //配置队列大小
            executor.setQueueCapacity(QUERE_CAPACITY);
            //配置线程池中的线程的名称前缀
            executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
            // rejection-policy:当pool已经达到max size的时候,如何处理新任务
            // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            //执行初始化
            executor.initialize();
            return executor;
        }
    }

    2.接口类

    import java.util.Map;
    public interface IAsyncService {
        public void executeAsync(int i);
    }

    3.实现类

    import com.newflows.sync.service.IAsyncService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    import java.util.Map;
    
    /**
     * 用于异步
     * ClassName:@Publisher
     * Description:单线程进入线程池执行
     **/
    @Service
    public class AsyncServiceImpl implements IAsyncService {
        private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);
    
        @Async("asyncServiceExecutor")
        @Override
        public void executeAsync(int index) {
            logger.info("start executeAsync"+"==>"+index);
            try {
                logger.info("当前运行用于异步的线程名称:" + Thread.currentThread().getName()+"==>"+index);
            } catch (Exception e) {
                e.printStackTrace();
            }
            logger.info("end executeAsync"+"==>"+index);
        }}

    4.控制层 

    import com.newflows.sync.service.IAsyncService;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
        private static final Logger logger = LoggerFactory.getLogger(UserController.class);
        @Autowired
        private IAsyncService asyncService;
    
        @RequestMapping(value = "/publish")
        @ResponseBody
        public String publish() {
            for (int i=0;i<2000;i++){
                asyncService.executeAsync(i);
            }
            return "ok";
        }
    }

     温馨提示:3的实现类中  @Async("asyncServiceExecutor") 一定要与 1中的线程配置中的 asyncServiceExecutor 方法名一样

    @Async调用中的事务处理机制  :原文链接:https://blog.csdn.net/fwk19840301/article/details/90082867

        在@Async标注的方法,同时也适用了@Transactional进行了标注;在其调用数据库操作之时,将无法产生事务管理的控制,原因就在于其是基于异步处理的操作。

         那该如何给这些操作添加事务管理呢?可以将需要事务管理操作的方法放置到异步方法内部,在内部被调用的方法上添加@Transactional.

        例如:  方法A,使用了@Async/@Transactional来标注,但是无法产生事务控制的目的。

                    方法B,使用了@Async来标注,  B中调用了C、D,C/D分别使用@Transactional做了标注,则可实现事务控制的目的。

     https://www.cnblogs.com/jpfss/p/10273129.html 

  • 相关阅读:
    二叉树中序遍历的非递归实现
    求树的遍历、树的叶子节点个数、树的高度、copy树
    javascript知识点汇总(running)
    IOS零碎知识点(积累中)
    Cuda learn record three
    Cuda learn record two
    找出字符串中的最长的回文子串
    Cuda learn record one
    Chrome 安装失败 错误代码 0X80070057
    Vs 2015 项目中include 无法打开源文件
  • 原文地址:https://www.cnblogs.com/gjq1126-web/p/12190432.html
Copyright © 2011-2022 走看看