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