異步任務與自定義線程池

線程池配置

/**
	 * 定義線程池
	 * @return
	 */
	@Bean("myThreadPool")
	public Executor asyncServiceExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(10);//配置核心線程數
		executor.setMaxPoolSize(20);//配置最大線程數
		executor.setKeepAliveSeconds(5);
		executor.setQueueCapacity(200);//配置隊列大小
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//拒絕策略
		executor.setWaitForTasksToCompleteOnShutdown(true);
		executor.initialize();//執行初始化
		return executor;
	}

異步任務

package com.test.service;
 
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
 
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
@Service
public class MyServiceImpl {
    //volatile保證了靜態變量的可見性(visibility),
    public static volatile AtomicInteger i = new AtomicInteger(0);
 
    /**
     * 無返回結果
     */
    @Async("myThreadPool")
    public void test() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("當前第"+ i.incrementAndGet() +"次執行");
    }
 
    /**
     * 有返回結果
     * @return
     */
    @Async("myThreadPool")
    public Future<String> test2() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new AsyncResult("當前第"+ i.incrementAndGet() +"次執行");
    }
}

開啓異步任務

package com.test;

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

@SpringBootApplication
@EnableAsync
public class MyTestApplication {

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

}

注意

注意:
關於@Async註解失效需要注意以下幾點:

  1.    註解的方法必須是public方法。
  2.    方法一定要從另一個類中調用,也就是從類的外部調用,類的內部調用是無效的。因爲@Transactional和@Async註解的實現都是基於Spring的AOP,而AOP的實現是基於動態代理模式實現的。那麼註解失效的原因就很明顯了,有可能因爲調用方法的是對象本身而不是代理對象,因爲沒有經過Spring容器。
  3.    異步方法使用註解@Async的返回值只能爲void或者Future。
  4.    自定義的線程池必須與@Async()不在同一個類中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章