• 【spring boot】13.在spring boot下使用多线程


    使用场景:

    方法处理到某一步,需要将信息交给另一个线程去处理!!

    ===================================================================================

    第一种:最简单的Runnable

        public void test(String msg){
            System.out.println(Thread.currentThread().getName()+":"+msg);
            Runnable runnable = dealMsg(msg);
        //将返回的runnable对象传入,并start()启动线程
         new Thread(runnable).start(); }
    //创建一个Runnable,重写run方法
    public
    Runnable dealMsg(String msg){ Runnable runnable = new Runnable() { @Override public void run() { System.out.println("新开线程中处理:"+msg); } }; return runnable; }

    ====================================================================================================

    第二种:自己创建JDK线程池,交给spring管理,然后将任务交给线程池即可

    1.创建线程池,交给spring管理

    package com.sxd.util;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    @Configuration
    public class ThreadConfig {
    
        /**
         *newFixedThreadPool
         创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
    
         newCachedThreadPool
         创建一个可缓存的线程池。这种类型的线程池特点是: 
         1).工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。 
         2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
    
         newSingleThreadExecutor
         创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,如果这个线程异常结束,会有另一个取代它,保证顺序执行(我觉得这点是它的特色)。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的 。
    
         newScheduleThreadPool
         创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。
         * @return
         */
        @Bean
        public ExecutorService getExecutorTools(){
            ExecutorService executorService = Executors.newFixedThreadPool(8);
            return  executorService;
        }
    
    }
    View Code

    2.使用它

    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Future;
    
    
    @Component
    public class Consumer1 {
    
    
        @Resource
        private ExecutorService executorService;
    
        
        public void test(String msg){
            System.out.println(Thread.currentThread().getName()+":"+msg);
    
    
            /**
             * 分类1:可以返回值的 Callable
             */
            Future fal  = executorService.submit(new Callable<String>() {
                @Override
                public String call() {
                    System.out.println(Thread.currentThread().getName()+":"+msg);
                    return "处理成功!";
                }
            });
    
            try {
                System.out.println(fal.get());
            }catch (Exception e){
                System.out.println(e);
            }
    
            /**
             * 分类2:不会返回值的 Runnable
             */
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+":"+msg);
                }
            });
    
            /**
             * 分类3:也可以这样
             */
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+":"+msg);
                }
            });
    
        }
    
    
    
    
    }
    View Code

    ====================================================================================================

    第三种:使用spring封装的线程池

    1.创建线程配置类【

    @ComponentScan("com.sxd") 标明会在哪个包下使用多线程  

    package com.sxd.util;
    
    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;
    
    @Configuration
    @ComponentScan("com.sxd")
    @EnableAsync
    // 线程配置类
    public class AsyncTaskConfig implements AsyncConfigurer {
    
        // ThredPoolTaskExcutor的处理流程
        // 当池子大小小于corePoolSize,就新建线程,并处理请求
        // 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
        // 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
        // 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁
    
        @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 null;
        }
    }
    View Code

    2.创建线程任务执行类

    package com.sxd.util;
    
    import java.util.Random;
    import java.util.concurrent.Future;
    
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.stereotype.Service;
    
    @Service
    // 线程执行任务类
    public class AsyncTaskService {
    
        Random random = new Random();// 默认构造方法
    
        @Async
        // 表明是异步方法
        // 无返回值
        public void executeAsyncTask(String msg) {
            System.out.println(Thread.currentThread().getName()+"开启新线程执行" + msg);
        }
    
        /**
         * 异常调用返回Future
         *
         * @param i
         * @return
         * @throws InterruptedException
         */
        @Async
        public Future<String> asyncInvokeReturnFuture(int i) throws InterruptedException {
            System.out.println("input is " + i);
            Thread.sleep(1000 * random.nextInt(i));
    
            Future<String> future = new AsyncResult<String>("success:" + i);// Future接收返回值,这里是String类型,可以指明其他类型
    
            return future;
        }
    }
    View Code

    3.使用它

    @Component
    public class Consumer1 {
    
    
        @Resource
        private AsyncTaskService asyncTaskService;
    
    
        public void test(String msg){
            System.out.println(Thread.currentThread().getName()+":"+msg);
    
            asyncTaskService.executeAsyncTask(msg);
    
        }
        
    }
    View Code

    ====================================================================================================

    第四种:在代码中启动异步处理最简单的代码

    public void test(){
        new Thread(()->doReplace(replaceLog)).start();         
    }
    
    public void doReplace(String replaceLog){
                      
                //异步处理的业务
    }

    ======================================

    就这么多,再补充噻!!

  • 相关阅读:
    java学习day2--java和javac命令的使用
    java学习day1--了解java及JDK环境变量的配置
    idea 修改console 日志区的背景
    微信的storage的操作
    python 基础
    shiro标签说明
    IDEA 修改编辑区的背景颜色
    java注解
    java的反射
    创建一个maven项目
  • 原文地址:https://www.cnblogs.com/sxdcgaq8080/p/8074567.html
Copyright © 2020-2023  润新知