当前位置:   article > 正文

Java线程池ThreadPoolTaskExecutor_java threadpooltaskexecutor

java threadpooltaskexecutor

在执行一个异步任务或并发任务时,往往是通过直接new Thread()方法来创建新的线程,这样做弊端较多,更好的解决方案是合理地利用线程池,使用线程池可以降低系统资源消耗、提高系统响应速度、方便线程并发数的管控。

线程池代码示例

@Configuration
@EnableAsync
public class ThreadPoolManager {

    Logger logger = LoggerFactory.getLogger(ThreadPoolManager.class);

    /**
     *  testAsyncTaskExecutor线程池
     * */
    @Bean("testAsyncTaskExecutor")
    public ThreadPoolTaskExecutor asynRecalculateExcutor(){
    
        logger.info("testAsyncTaskExecutor异步线程池开启");
        
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程数
        executor.setCorePoolSize(50);
        //最大线程数
        executor.setMaxPoolSize(200);
        //核心线程数之外的线程存活时间
        executor.setKeepAliveSeconds(60*2);
        //队列大小
        executor.setQueueCapacity(1500);
        //线程名称前缀
        executor.setThreadNamePrefix("test_Async_Task_Executor_");
        //异步重算线程池修饰器。
        executor.setTaskDecorator(new ContextCopyingDecorator());
        //当任务完成后,长时间无待处理任务时,销毁线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        return executor;
    }

    /**
     * 线程池修饰类
     * 注意线程池中有的线程是一直存在一直被复用的,
     * 所以线程执行完成后需要在TaskDecorator的finally方法中移除传递的上下文对象,否则就存在内存泄漏的问题。
     * TaskDecorator是一个执行回调方法的装饰器,主要应用于传递上下文,或者提供任务的监控/统计信息。
     */
    public class ContextCopyingDecorator implements TaskDecorator {
        @Override
        public Runnable decorate(Runnable runnable) {
            try {
                RequestAttributes context = RequestContextHolder.currentRequestAttributes();
                Map<String,String> previous = MDC.getCopyOfContextMap();
                SecurityContext securityContext = SecurityContextHolder.getContext();
                return () -> {
                    try {
                        RequestContextHolder.setRequestAttributes(context);
                        MDC.setContextMap(previous);
                        SecurityContextHolder.setContext(securityContext);
                        runnable.run();
                    } finally {
                        RequestContextHolder.resetRequestAttributes();
                        MDC.clear();
                        SecurityContextHolder.clearContext();
                    }
                };
            } catch (IllegalStateException e) {
                return runnable;
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

如何使用?

1、注入bean使用

@Resource(name = "testAsyncTaskExecutor")
ThreadPoolTaskExecutor executor;
  • 1
  • 2

2、@Async注解异步方法

//在项目中, 偶尔需要使用异步的方式去执行任务.所以,我们可以引入多线程的使用,SpringBoot中支持多线程,使用@EnableAsync注解就可以使用多线程了,@Async放在需要异步执行的方法上,非常简单方便的使用多线程去完成任务.

    @Async("testAsyncTaskExecutor")
    @Override
    public void test() {
        //代码
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

执行execute()方法和submit()方法的区别是什么呢

1、execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;

2、submit()方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个future对象可以判断任务是否执行成功,并且可以通过future的get()方法来获取返回值,get()方法会阻塞当前线程直到任务完成,而使用get(long timeout,TimeUnit unit) 方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。

ThreadPoolTaskExecutor部分源码

	@Override
	public void execute(Runnable task) {
		Executor executor = getThreadPoolExecutor();
		try {
			executor.execute(task);
		}
		catch (RejectedExecutionException ex) {
			throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
		}
	}

	@Override
	public void execute(Runnable task, long startTimeout) {
		execute(task);
	}

	@Override
	public Future<?> submit(Runnable task) {
		ExecutorService executor = getThreadPoolExecutor();
		try {
			return executor.submit(task);
		}
		catch (RejectedExecutionException ex) {
			throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/1008893
推荐阅读
相关标签
  

闽ICP备14008679号