zoukankan      html  css  js  c++  java
  • 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
    诸葛
  • 相关阅读:
    (转)【web前端培训之前后端的配合(中)】继续昨日的故事
    ural(Timus) 1136. Parliament
    scau Josephus Problem
    ACMICPC Live Archive 6204 Poker End Games
    uva 10391 Compound Words
    ACMICPC Live Archive 3222 Joke with Turtles
    uva 10132 File Fragmentation
    uva 270 Lining Up
    【转】各种字符串哈希函数比较
    uva 10905 Children's Game
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/14296099.html
Copyright © 2011-2022 走看看