异步任务与自定义线程池

线程池配置

/**
	 * 定义线程池
	 * @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()不在同一个类中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章