• 【快学springboot】10.使用@Async注解创建多线程,自定义线程池


    说明

    使用@Async注解创建多线程非常的方便,还可以通过配置,实现线程池。比直接使用线程池简单太多。而且在使用上跟普通方法没什么区别,加上个@Async注解即可实现异步调用。

    用法

    AsyncTask.java

    @Component
    public class AsyncTask {
     private static final Logger LOG = LoggerFactory.getLogger(AsyncTask.class);
     @Async
     public void register(){
     LOG.info("多线程开始注册模拟");
     try {
     Thread.sleep(1000*1);
     } catch (InterruptedException e) {
     e.printStackTrace();
     }
     LOG.info("多线程注册成功");
     }
    }
    

    这里只是做一个简单地打印输出,使用Log4J打印是为了方便看到线程名

    AsyncTaskController.java

    @RestController
    @RequestMapping(value = "/async")
    public class AsyncTaskController {
     private final static Logger LOG = LoggerFactory.getLogger(AsyncTaskController.class);
     @Autowired
     private AsyncTask asyncTask;
     @GetMapping(value = "/test")
     public Object test(){
     for (int i = 0; i < 10; i++) {
     asyncTask.register();
     }
     System.out.println("主线程结束");
     return "OK";
     }
    }
    

    这里循环创建10个线程

    启用Async

    启用Async需要添加@EnableAsync注解

    @SpringBootApplication
    @ServletComponentScan
    @EnableAsync
    public class App {
     public static void main(String[] args) {
     SpringApplication.run(App.class, args);
     }
    }
    

    结果

    【快学springboot】10.使用@Async注解创建多线程,自定义线程池

    可以看到,主线程结束已经结束。可证证明多线程起了效果。另外通过查看线程名,可以看到创建了10个线程去执行。


    使用线程池

    通过上面的结果可以看出,直接使用@Async注解是直接创建线程去执行的。但是在实际开发中,都应该使用线程池去管理线程,节省线程开销。

    配置

    TaskExecutorConfig.class

    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.AsyncConfigurer;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    import java.util.concurrent.Executor;
    
    @Configuration
    public class TaskExecutorConfig implements AsyncConfigurer {
     /**
     * Set the ThreadPoolExecutor's core pool size.
     */
     private static final int CORE_POOL_SIZE = 2;
     /**
     * Set the ThreadPoolExecutor's maximum pool size.
     */
     private static final int MAX_POOL_SIZE = 2;
     /**
     * Set the capacity for the ThreadPoolExecutor's BlockingQueue.
     */
     private static final int QUEUE_CAPACITY = 10;
     /**
     * 通过重写getAsyncExecutor方法,制定默认的任务执行由该方法产生
     *
     * 配置类实现AsyncConfigurer接口并重写getAsyncExcutor方法,并返回一个ThreadPoolTaskExevutor
     * 这样我们就获得了一个基于线程池的TaskExecutor
     */
     @Override
     public Executor getAsyncExecutor() {
     ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
     taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
     taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
     taskExecutor.setQueueCapacity(QUEUE_CAPACITY);
     taskExecutor.initialize();
     return taskExecutor;
     }
    }
    

    这里设置了最大两个线程。

    测试

    重启程序测试下:

    【快学springboot】10.使用@Async注解创建多线程,自定义线程池

    结果

    可以看到只有两个线程在执行,证明配置的线程池起作用了。

  • 相关阅读:
    webstorm 格式化代码及常用快捷键
    Jetbrains 2018 等系列软件激活破解除去黄色警告框方法(含多个平台)
    HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
    为什么macos开机黑屏但是有声音?
    mac 回车键、空格键失灵(非物理原因)解决方法
    在VS代码中使用版本控制
    在Visual Studio代码中使用Flask
    [IOI1999]花店橱窗布置(DP路径记录)
    leetcode:Minimum Path Sum(路线上元素和的最小值)【面试算法题】
    c/c++ 复习基础要点01-const指针、指针函数 函数指针、new/delete与malloc/free区别与联系
  • 原文地址:https://www.cnblogs.com/happy4java/p/11205818.html
Copyright © 2020-2023  润新知