springboot中的异步调用(hello world)

需要在启动类加入@EnableAsync使异步调用@Async注解生效

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
@MapperScan({"com.example.demo.dao","com.example.demo.practice"})
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

 

springboot的线程池配置

创建一个配置类AsyncExecutorConfig,用来定义如何创建一个ThreadPoolTaskExecutor,要使用@Configuration和@EnableAsync这两个注解,表示这是个配置类,并且是线程池的配置类,如下所示:

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
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.ThreadPoolExecutor;


/**
 * 异步线程池
 */
@Slf4j
@Configuration
@EnableAsync
public class AsyncExecutorConfig {

/**
 *   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
 *	当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
 *  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
 */

    /** 核心线程数(默认线程数) */
    private static final int corePoolSize = 2;
    /** 最大线程数 */
    private static final int maxPoolSize = 2;
    /** 允许线程空闲时间(单位:默认为秒) */
    private static final int keepAliveTime = 2;
    /** 缓冲队列大小 */
    private static final int queueCapacity = 999;
    /** 线程池名前缀 */
    private static final String threadNamePrefix = "Async-practice-";

    @Bean("asyncExecutor") // bean的名称,默认为首字母小写的方法名,如果不声明则会使用方法名
    public ThreadPoolTaskExecutor asyncExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveTime);
        executor.setThreadNamePrefix(threadNamePrefix);

        // 线程池对拒绝任务的处理策略
        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        executor.initialize();
        return executor;
    }

}

使用

controller:

package com.example.demo.controller;

import com.example.demo.service.TestService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/mainController")
@AllArgsConstructor(onConstructor_ = {@Autowired})
@Api(tags = "测试异步调用",value = "类标识value")
public class AsyncController {


    @GetMapping(value = "/testYB")
    @ApiOperation(value = "测试异步注解 @Async" ,notes = "")
    public String testYB(){
        return testService.testYB();
    }




    @GetMapping(value = "/mainMethod")
    @ApiOperation(value = "测试数据库连接" ,notes = "方法描述notes")
    public int main(){
        return testService.getServiceValues();
    }

    TestService testService;

}

service:

package com.example.demo.service;

import com.example.demo.dao.TestDao;
import com.example.demo.util.rest.HttpParams;
import com.example.demo.util.rest.Mail;
import com.example.demo.util.rest.Rest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@AllArgsConstructor(onConstructor_ = {@Autowired})
public class TestService {

    public String  testYB(){
        log.info("主线程开始"+new Date().toString());
        for(int i = 1; i <= 5; i++){
            testYbLongTime.longTime();
        }
        log.info("主线程结束"+new Date().toString());
        return "service返回";
    }
    public void testYBVoid(){
        System.out.println("开始"+new Date().toString());
        testYbLongTime.longTimeVoid();
        System.out.println("结束"+new Date().toString());
    }


    /**
     * @Method
     * @Author yu
     * @Version  1.0
     * @Description 测试配置文件的注入
     * @param
     * @Return
     * @Exception
     * @Date 2020/5/9
     */
    public int getServiceValues(){
        System.out.println(mail.getPort()+"--"+mail.getUrl());
        List<HttpParams>  aa = rest.getParamsList();
        Map<String,String> bb = new HashMap<>();
        bb.put("1","2") ;
        bb.put("3","3") ;
        bb.put("4","4") ;

//        lamda2foreach.add(bb);
        System.out.println(lamda2foreach.iMap(bb));
        return testDao.testMethod();
    }

    TestDao testDao;
    Mail mail;
    Rest rest;
    Lamda2foreach lamda2foreach;
    TestYbLongTime testYbLongTime;
}

异步方法:

package com.example.demo.service;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.Date;

@Slf4j
@Component
public class TestYbLongTime {
    
    @Async("asyncExecutor")
    public void longTimeVoid(){
        try {
            Thread.sleep(1000*5);
            log.info("线程完成");
            log.info("123");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async("asyncExecutor")
    public void longTime(){
        try {
            Thread.sleep(1000*5);
            log.info("异步线程完成"+new Date());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

注意事项:

1>、:@Async()没有指定线程池时,默认是使用springboot默认线程池,且每次都会创建线程,所以最好我们来自定义一个线程池。

2>、调用异步的方法和异步方法不要再同一个类中,使用注入的方式调用

3>、异步方法不要使用private、static修饰

 

在spring中的配置:(没有用过可以参考:https://blog.csdn.net/Muscleheng/article/details/81409672

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章