• Spring Cloud微服务实战 打造企业级优惠券系统 3-7 SpringBoot 异步任务(任务池)


    0    课程地址

    http://coding.imooc.com/lesson/380.html#mid=28275

    1    浓缩精华
    1.1  浓缩精华

    4.2  多个线程池的配置使用

    2    个人关注
    2.1  个人关注

    4.1  异步任务demo

    4.2  线程池的配置使用

    4.2  多个线程池的配置使用

    4.2  TimeUnit.SECONDS.sleep(5);的使用

    4.3  超时方法使用

    3    课程内容
    3.1  4.1,4.2
    4    代码演练
    4.1  异步任务demo(非线程池)

    测试类

    package com.imooc.springboot.application;
    
    import com.imooc.springboot.application.async.AsyncService;
    import lombok.extern.slf4j.Slf4j;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    /**
     * TestAsyncService
     *
     * @author 魏豆豆
     * @date 2021/4/6
     */
    @Slf4j
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class TestAsyncService {
    
        @Autowired
        private AsyncService asyncService;
    
        @Test
        public void executeAsyncService() throws InterruptedException {
            asyncService.asyncNotReturn();
            log.info("进入无参异步方法");
        }
    
        @Test
        public void executeAsyncService2() throws InterruptedException {
            asyncService.asyncHasReturn();
            //Thread.sleep(10);
            log.info("进入有参异步方法");
        }
    
    }

    异步任务Service

    package com.imooc.springboot.application.async;
    
    import lombok.extern.java.Log;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.stereotype.Service;
    
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    /**
     * AsyncService
     *
     * @author 魏豆豆
     * @date 2021/4/6
     */
    @Slf4j
    @Service
    public class AsyncService {
    
        /**
         * 没有返回的异步任务
         */
        @Async
        public void asyncNotReturn() throws InterruptedException {
            //记一下sleep
            log.info("无返回线程名字为======================="+Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(5);
        }
    
        /**
         * 没有返回的异步任务
         * @return
         */
        @Async
        public Future<Integer> asyncHasReturn() throws InterruptedException {
            log.info("有返回线程名字为======================="+Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(6);
    
            //记一下
            return new AsyncResult<>(100);
        }
    
    }

    顶部启动类:

    package com.imooc.springboot.application;
    
    import org.springframework.boot.Banner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.WebApplicationType;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    /**
     * SpringBootApplication
     *
     * @author 魏豆豆
     * @date 2021/1/13
     */
    @SpringBootApplication
    @EnableScheduling
    @EnableAsync//允许异步任务
    public class SpringBootStudyApplication {
        public static void main(String [] args){
            //第一种方式启动
            //SpringApplication.run(SpringBootStudyApplication.class,args);
    
            //第二种方式启动
            /*SpringApplication springApplication = new SpringApplication(SpringBootStudyApplication.class);
            //关掉打印logo相关日志
            springApplication.setBannerMode(Banner.Mode.OFF);
            //非wub启动,控制台启动后会关闭,不会一直保持开启状态
            springApplication.setWebApplicationType(WebApplicationType.NONE);
            springApplication.run(args);*/
    
            //第三种方式启动 链式调用
           new SpringApplicationBuilder(SpringBootStudyApplication.class)
                    //.bannerMode(Banner.Mode.OFF)
                   // .web(WebApplicationType.NONE)
                   .run(args);
        }
    
    }

    打印日志:

    2021-04-11 07:46:03.139  INFO 16808 --- [           main] c.i.s.application.TestAsyncService       : 进入无参异步方法
    2021-04-11 07:46:03.149  INFO 16808 --- [           main] c.i.s.application.TestAsyncService       : 进入有参异步方法
    2021-04-11 07:46:03.159  INFO 16808 --- [cTaskExecutor-1] c.i.s.application.async.AsyncService     : 无返回线程名字为=======================SimpleAsyncTaskExecutor-1
    2021-04-11 07:46:03.160  INFO 16808 --- [cTaskExecutor-2] c.i.s.application.async.AsyncService     : 有返回线程名字为=======================SimpleAsyncTaskExecutor-2
    2021-04-11 07:46:03.168  INFO 16808 --- [       Thread-2] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'
    2021-04-11 07:46:03.187  INFO 16808 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'bbb'
    4.2  异步任务demo(线程池配置)

    测试类

    package com.imooc.springboot.application;
    
    import com.imooc.springboot.application.async.AsyncService2;
    import lombok.extern.slf4j.Slf4j;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Future;
    
    /**
     * TestAsyncService
     *
     * @author 魏豆豆
     * @date 2021/4/6
     */
    @Slf4j
    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class TestAsyncService2 {
    
        @Autowired
        private AsyncService2 asyncService;
    
        @Test
        public void executeAsyncService() throws InterruptedException {
            asyncService.asyncNotReturn();
            log.info("进入无参异步方法");
        }
    
        @Test
        public void executeAsyncService2() throws InterruptedException, ExecutionException {
            //记一下时间的
            long start = System.currentTimeMillis();
            System.out.println("start=========================="+start);
            Future<Integer> future = asyncService.asyncHasReturn();
    
            //Thread.sleep(10);
            log.info("进入有参异步方法");
            log.info("future.get",future.get());
            log.info("时间差=====",System.currentTimeMillis()-start);
        }
    
    }

    异步任务Service2

    package com.imooc.springboot.application.async;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.scheduling.annotation.AsyncResult;
    import org.springframework.stereotype.Service;
    
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    /**
     * AsyncService
     *
     * @author 魏豆豆
     * @date 2021/4/6
     */
    @Slf4j
    @Service
    public class AsyncService2 {
    
        /**
         * 没有返回的异步任务
         */
        @Async("aaa")
        public void asyncNotReturn() throws InterruptedException {
            //记一下sleep
            log.info("无返回自定义线程名字为======================="+Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(5);
        }
    
        /**
         * 没有返回的异步任务
         * @return
         */
        @Async("bbb")
        public Future<Integer> asyncHasReturn() throws InterruptedException {
            log.info("有返回自定义线程名字为======================="+Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(6);
    
            //记一下
            return new AsyncResult<>(100);
        }
    
    }

    线程池配置类:

    package com.imooc.springboot.application.config;
    
    import com.alibaba.fastjson.JSON;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.AsyncConfigurer;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    import java.lang.reflect.Method;
    import java.util.concurrent.Executor;
    import java.util.concurrent.ThreadPoolExecutor;
    
    
    /**
     * AsyncThreadPoolConfig
     * 自定义线程池
     * @author 魏豆豆
     * @date 2021/4/7
     */
    @Configuration
    @Slf4j
    //记一下实现的接口(实现异步任务配置类)
    public class AsyncThreadPoolConfig implements AsyncConfigurer {
    
    
        @Bean//将线程池初始化到springioc容器中
        public Executor aaa() {
            //1     线程池设置参数
            ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
            threadPoolTaskExecutor.setCorePoolSize(20);//核心线程20个,能同时处理20个客户端请求
            threadPoolTaskExecutor.setQueueCapacity(10);//缓冲队列允许10个线程等待
            threadPoolTaskExecutor.setMaxPoolSize(30);//超出缓冲队列最多允许30个线程处理
            threadPoolTaskExecutor.setKeepAliveSeconds(60);//线程存活时间60秒
            threadPoolTaskExecutor.setThreadNamePrefix("wdd_");//线程名称前缀
    
            //记一下
            threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            threadPoolTaskExecutor.setAwaitTerminationSeconds(60);
    
            //2     拒绝策略
            threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    
            //3     线程池初始化
            threadPoolTaskExecutor.initialize();
            return threadPoolTaskExecutor;
        }
    
        @Bean//将线程池初始化到springioc容器中
        public Executor bbb() {
            //1     线程池设置参数
            ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
            threadPoolTaskExecutor.setCorePoolSize(20);//核心线程20个,能同时处理20个客户端请求
            threadPoolTaskExecutor.setQueueCapacity(10);//缓冲队列允许10个线程等待
            threadPoolTaskExecutor.setMaxPoolSize(30);//超出缓冲队列最多允许30个线程处理
            threadPoolTaskExecutor.setKeepAliveSeconds(60);//线程存活时间60秒
            threadPoolTaskExecutor.setThreadNamePrefix("hcx_");//线程名称前缀
    
            //记一下
            threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            threadPoolTaskExecutor.setAwaitTerminationSeconds(60);
    
            //2     拒绝策略
            threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    
            //3     线程池初始化
            threadPoolTaskExecutor.initialize();
            return threadPoolTaskExecutor;
        }
    
    
        /**
         * 该方法仅能处理无返回值异步任务的异常,有返回值的异步任务异常客户端处理
         * @return
         */
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return new AsyncExceptionHandler();
        }
    
        //记一下,异常处理类实现异常处理接口
        class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler{
    
            @Override
            public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
                //1     打印日志
                log.info("wdd异常打印========"+throwable.getMessage(),method.getName(),JSON.toJSONString(objects));
    
                //2     正常跑出异常
                throwable.printStackTrace();
    
                //3     发短信或者邮件通知运维人员
                //todo
            }
        }
    }

    顶部启动类:(同上)

    打印日志:

    2021-04-11 07:48:51.441  INFO 15872 --- [           main] c.i.s.application.TestAsyncService2      : 进入无参异步方法
    start==========================1618098531455
    2021-04-11 07:48:51.455  INFO 15872 --- [           main] c.i.s.application.TestAsyncService2      : 进入有参异步方法
    2021-04-11 07:48:51.492  INFO 15872 --- [          hcx_1] c.i.s.application.async.AsyncService2    : 有返回自定义线程名字为=======================hcx_1
    2021-04-11 07:48:51.492  INFO 15872 --- [          wdd_1] c.i.s.application.async.AsyncService2    : 无返回自定义线程名字为=======================wdd_1
    2021-04-11 07:48:57.504  INFO 15872 --- [           main] c.i.s.application.TestAsyncService2      : future.get
    2021-04-11 07:48:57.504  INFO 15872 --- [           main] c.i.s.application.TestAsyncService2      : 时间差=====
    2021-04-11 07:48:57.520  INFO 15872 --- [       Thread-2] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'
    2021-04-11 07:48:57.520  INFO 15872 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'bbb'
    2021-04-11 07:48:57.520  INFO 15872 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'aaa'
    4.3  异步任务demo(超时方法应用)

    测试类:

     @Test
        public void executeAsyncService2() throws InterruptedException, ExecutionException, TimeoutException {
            //记一下时间的
            long start = System.currentTimeMillis();
            System.out.println("start=========================="+start);
            Future<Integer> future = asyncService.asyncHasReturn();
    
            //Thread.sleep(10);
            log.info("进入有参异步方法");
            //log.info("future.get",future.get());
            log.info("超时方法=======================",future.get(1,TimeUnit.SECONDS));
            log.info("时间差=====",System.currentTimeMillis()-start);
        }

    其他方法如4.2

    打印日志:

    start==========================1618099228046
    2021-04-11 08:00:28.055  INFO 11628 --- [           main] c.i.s.application.TestAsyncService2      : 进入有参异步方法
    2021-04-11 08:00:28.065  INFO 11628 --- [          hcx_1] c.i.s.application.async.AsyncService2    : 有返回自定义线程名字为=======================hcx_1
    
    java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:205)
        at com.imooc.springboot.application.TestAsyncService2.executeAsyncService2(TestAsyncService2.java:46)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
        at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    
    2021-04-11 08:00:29.075  INFO 11628 --- [       Thread-2] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'taskScheduler'
    2021-04-11 08:00:29.079  INFO 11628 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'bbb'
    2021-04-11 08:00:34.068  INFO 11628 --- [       Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'aaa'
    
    Process finished with exit code -1
    诸葛
  • 相关阅读:
    一个合格的程序员应该读过哪些书
    一个程序员如何快速赚到一百万?
    如何创造财富?硅谷创业之父 Paul Graham 《黑客与画家》思维导图
    java 入门书籍(java7)
    活动预售和预热的目的
    活动策划
    店铺费率把控
    如何通过店铺数据分析店铺异常原因?
    刷单三大目的?如何安全、低成本、高效完成刷单
    活动报名技巧之——天天特卖
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/14296099.html
Copyright © 2020-2023  润新知