栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用ThreadPoolTaskExecutor与@Async快速实现多线程异步操作

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用ThreadPoolTaskExecutor与@Async快速实现多线程异步操作

前言

ThreadpoolTaskExecutor相对于ThreadpoolExecutor来说,是使用了ThreadPoolExecutor并增强,扩展了更多特性。它是Spring提供的线程池,帮助我们快速创建一个可用的线程池来使用。

@Async是Spring的注解,可以加在类或方法上。通俗的来讲,如果加上了这个注解,那么该类或者该方法在使用时将会进行异步处理,也就是创建一个线程来实现这个类或者方法,实现多线程。

使用

1、配置线程池

package com.czf.connect.config;

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;


@EnableAsync	//表示开启多线程
@Configuration
public class ThreadPoolConfig {
    
    private static final int CORE_POOL_SIZE = 20;
    
    private static final int MAX_POOL_SIZE = 40;
    
    private static final int QUEUE_CAPACITY = 200;
    
    private static final int KEEP_ALIVE_SEConDS = 60;

    @Bean(name = "threadPoolTaskExecutor")	//ThreadPoolTaskExecutor不会自动创建ThreadPoolExecutor,需要手动调initialize才会创建。如果@Bean就不需手动,会自动InitializingBean的afterPropertiesSet来调initialize
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置线程池最大线程数
        executor.setMaxPoolSize(MAX_POOL_SIZE);
        // 线程池活跃的线程数
        executor.setCorePoolSize(CORE_POOL_SIZE);
        // 设置线程队列最大线程数
        executor.setQueueCapacity(QUEUE_CAPACITY);
        // 线程池维护线程所允许的空闲时间
        executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        executor.setThreadNamePrefix("task-async");//线程前缀名称
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

2、需要异步操作的方法或类:

@Slf4j
@Component		//将该类注入到容器中
public class AsyncTest {
    @Async("threadPoolTaskExecutor")		//调用该线程池
    public void task() throws InterruptedException {
        Thread.sleep(4000);
        log.info("task异步处理");
    }
}

3、测试类

@Slf4j
@RestController
public class PoolTest {

    @Autowired
    private AsyncTest asyncTest;

    @RequestMapping("/pool")
    public void poolTest() throws InterruptedException {
        log.info("主线程开始");
        asyncTest.task();
        log.info("主线程结束");
    }
}

4、结果:

可以看出是由不同的线程执行。

注意要点

1、@Async需要在Spring环境下才能启动,使用的是AOP动态代理技术

2、@Async使用的是动态代理来实现异步调用,因此不能够在同一个类中进行调用。方法一定要从另一个类中调用,也就是从类的外部调用,类的内部调用是无效的,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器。

3、注解的方法必须是public方法

4、需要在@SpringBootApplication启动类或者@configure注解类上 添加注解@EnableAsync启动多线程注解。

5、@Async就会对标注的方法开启异步多线程调用,注意,这个方法的类一定要交给spring容器来管理。

6、异步方法使用注解@Async的返回值只能为void或者Future。

有返回值的异步处理

上述方法实现的是无返回值的异步操作,接下来实现的是有返回值的异步操作,即返回值为Future。

异步方法

    @Async("threadPoolTaskExecutor")
    public Future task1() throws InterruptedException {
        log.info("异步处理开始");
        Thread.sleep(2000);
        return new AsyncResult("异步处理");
    }
    
    @Async("threadPoolTaskExecutor")
    public Future task2() throws InterruptedException {
        log.info("异步处理开始");
        User2 user2 = new User2();
        user2.setName("zhangsan");
        user2.setId(1);
        Thread.sleep(2000);
        return new AsyncResult(user2);
    }

接口实现

    @RequestMapping("/pool1")
    public String poolTest1() throws InterruptedException, ExecutionException {
        log.info("主线程开始");
        Future stringFuture = asyncTest.task1();
        log.info("主线程结束");
        Thread.sleep(2000);
        log.info("{}",stringFuture.get());
        return stringFuture.get();
    }

    @RequestMapping("/pool2")
    public User2 poolTest2() throws InterruptedException, ExecutionException {
        log.info("主线程开始");
        Future stringFuture = asyncTest.task2();
        log.info("主线程结束");
        Thread.sleep(2000);
        log.info("{}",stringFuture.get());
        return stringFuture.get();
    }

poolTest1方法:

poolTest2方法:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/708365.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号