zoukankan      html  css  js  c++  java
  • Spring Boot实践——多线程

    多线程

      Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解声明其是一个异步任务。

      此外,还提供一种Java的实现方式,多种方式去尝试如何去实现多线程。

    实现

    一、基于Spring

    1、配置类

    import java.util.concurrent.Executor;
    
    import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.AsyncConfigurer;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    /**
     * @Description: 配置类实现AsyncConfigurer接口,并重写getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor,
     * 这样我们就获得一个基于线程池TaskExecutor
     * @ClassName: CustomMultiThreadingConfig
     * @Author: OnlyMate
     * @Date: 2018年9月21日 下午2:50:14
     */
    @Configuration
    @ComponentScan("com.only.mate.springboot.multithreading")
    @EnableAsync//利用@EnableAsync注解开启异步任务支持
    public class CustomMultiThreadingConfig implements AsyncConfigurer{
    
        @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            taskExecutor.setCorePoolSize(5);
            taskExecutor.setMaxPoolSize(10);
            taskExecutor.setQueueCapacity(25);
            taskExecutor.initialize();
            return taskExecutor;
        }
    
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler();
        }
        
    }

    2、创建线程任务

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    
    /**
     * @Description: 创建线程任务服务
     * @ClassName: CustomMultiThreadingService
     * @Author: OnlyMate
     * @Date: 2018年9月21日 下午3:17:57
     */
    @Service
    public class CustomMultiThreadingService {
        private Logger logger = LoggerFactory.getLogger(CustomMultiThreadingService.class);
        /**
         * @Description:通过@Async注解表明该方法是一个异步方法,
         * 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
         * @Title: executeAysncTask1
         * @Date: 2018年9月21日 下午2:54:32
         * @Author: OnlyMate
         * @Throws
         * @param i
         */
        @Async
        public void executeAysncTask1(Integer i){
            logger.info("CustomMultiThreadingService ==> executeAysncTask1 method: 执行异步任务{} ", i);
        }
        
        /**
         * @Description:通过@Async注解表明该方法是一个异步方法,
         * 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
         * @Title: executeAsyncTask2
         * @Date: 2018年9月21日 下午2:55:04
         * @Author: OnlyMate
         * @Throws
         * @param i
         */
        @Async
        public void executeAsyncTask2(Integer i){
            logger.info("CustomMultiThreadingService ==> executeAsyncTask2 method: 执行异步任务{} ", i);
        }
    }

    3、触发线程任务

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.only.mate.springboot.multithreading.CustomMultiThreadingService;
    
    /**
     * @Description:自定义多线程Controller
     * @ClassName: CustomMultiThreadingController
     * @Author: OnlyMate
     * @Date: 2018年9月21日 下午3:02:49
     */
    @Controller
    @RequestMapping(value="/multithreading")
    public class CustomMultiThreadingController {
        @Autowired
        private CustomMultiThreadingService customMultiThreadingService;
        
        @ResponseBody
        @RequestMapping(value="/dotask")
        public String doTask() {
            for (int i=0;i<10;i++){
                customMultiThreadingService.executeAysncTask1(i);
                customMultiThreadingService.executeAsyncTask2(i);
            }
            
            return "success";
        }
    }

    4、效果图

    访问http://localhost:8088/springboot/multithreading/dotask

     二、基于Java

    1、异步线程调度管理器

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @Description: 异步线程调度管理器
     * @ClassName: CustomAsyncScheduler
     * @Author: OnlyMate
     * @Date: 2018年9月21日 下午3:25:40
     */
    public class CustomAsyncScheduler {
        private volatile static CustomAsyncScheduler instance;
        private static ThreadPoolExecutor chnlBackendQueryPool;
    
        private CustomAsyncScheduler() {
        }
    
        @SuppressWarnings({ "rawtypes", "static-access", "unchecked" })
        public static CustomAsyncScheduler getInstance() {
            if (instance == null) {
                synchronized (CustomAsyncScheduler.class) {
                    if (instance == null) {
                        instance = new CustomAsyncScheduler();
    
                        BlockingQueue queue = new LinkedBlockingQueue();
                        chnlBackendQueryPool = new ThreadPoolExecutor(50, 100, 30, TimeUnit.SECONDS, queue);
                        chnlBackendQueryPool.allowCoreThreadTimeOut(true);
                        instance.setChnlBackendQueryPool(chnlBackendQueryPool);
                    }
                }
            }
            return instance;
        }
    
        public ThreadPoolExecutor getChnlBackendQueryPool() {
            return chnlBackendQueryPool;
        }
    
        public static void setChnlBackendQueryPool(ThreadPoolExecutor chnlBackendQueryPool) {
            CustomAsyncScheduler.chnlBackendQueryPool = chnlBackendQueryPool;
        }
    
        public static void setInstance(CustomAsyncScheduler instance) {
            CustomAsyncScheduler.instance = instance;
        }
    
    }

    2、创建线程任务

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    
    /**
     * @Description: 创建线程任务服务
     * @ClassName: CustomMultiThreadingService
     * @Author: OnlyMate
     * @Date: 2018年9月21日 下午3:17:57
     */
    @Service
    public class CustomMultiThreadingService {
        private Logger logger = LoggerFactory.getLogger(CustomMultiThreadingService.class);
        /**
         * @Description:通过@Async注解表明该方法是一个异步方法,
         * 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
         * @Title: executeAysncTask1
         * @Date: 2018年9月21日 下午2:54:32
         * @Author: OnlyMate
         * @Throws
         * @param i
         */
        @Async
        public void executeAysncTask1(Integer i){
            logger.info("CustomMultiThreadingService ==> executeAysncTask1 method: 执行异步任务{} ", i);
        }
        
        /**
         * @Description:通过@Async注解表明该方法是一个异步方法,
         * 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
         * @Title: executeAsyncTask2
         * @Date: 2018年9月21日 下午2:55:04
         * @Author: OnlyMate
         * @Throws
         * @param i
         */
        @Async
        public void executeAsyncTask2(Integer i){
            logger.info("CustomMultiThreadingService ==> executeAsyncTask2 method: 执行异步任务{} ", i);
        }
        
        /**
         * @Description: 异步线程调度管理器创建线程任务
         * @Title: executeAsyncTask3
         * @Date: 2018年9月21日 下午3:32:28
         * @Author: OnlyMate
         * @Throws
         * @param i
         */
        public void executeAsyncTask3(Integer i){
            CustomAsyncScheduler.getInstance().getChnlBackendQueryPool().execute(new Runnable() {
                @Override
                public void run() {
                    logger.info("CustomMultiThreadingService ==> executeAsyncTask3 method: 执行异步任务{} ", i);                
                }
            });
            
        }
    }

    3、触发线程任务

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.only.mate.springboot.multithreading.CustomMultiThreadingService;
    
    /**
     * @Description:自定义多线程Controller
     * @ClassName: CustomMultiThreadingController
     * @Author: OnlyMate
     * @Date: 2018年9月21日 下午3:02:49
     */
    @Controller
    @RequestMapping(value="/multithreading")
    public class CustomMultiThreadingController {
        @Autowired
        private CustomMultiThreadingService customMultiThreadingService;
        
        @ResponseBody
        @RequestMapping(value="/dotask")
        public String doTask() {
            for (int i=0;i<10;i++){
                customMultiThreadingService.executeAysncTask1(i);
                customMultiThreadingService.executeAsyncTask2(i);
            }
            
            return "success";
        }
        
        @ResponseBody
        @RequestMapping(value="/dojob")
        public String doJob() {
            for (int i=0;i<10;i++){
                customMultiThreadingService.executeAysncTask1(i);
                customMultiThreadingService.executeAsyncTask2(i);
                customMultiThreadingService.executeAsyncTask3(i);
            }
            return "success";
        }
    }

    4、效果图

    访问http://localhost:8088/springboot/multithreading/dojob

  • 相关阅读:
    linux查看python安装位置
    Linux 重命名
    Linux 解压 压缩文件
    linux下文件的复制、移动与删除
    设计模式-命令模式
    设计模式-心得
    设计模式-责任链模式
    ajax跨域问题以及解决方案
    强者运强
    管理者法则
  • 原文地址:https://www.cnblogs.com/onlymate/p/9686740.html
Copyright © 2011-2022 走看看