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 

原文地址:https://www.cnblogs.com/gjq1126-web/p/12190432.html