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

 

 

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