• SSM-使用@Async和创建ThreadPoolTaskExecutor线程池


    线程池具体配置建议请看 : http://t.csdn.cn/nWaGH

    直接在项目中使用的线程池

    在applicationContext.xml里添加

        <bean id="userService" class="com.ssm.service.impl.UserServiceImpl">
            <property name="executor">
                <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
                    <property name="threadNamePrefix" value="user-"/>
                    <property name="corePoolSize" value="20"/>
                    <property name="maxPoolSize" value="20"/>
                    <property name="keepAliveSeconds" value="300"/>
                    <property name="queueCapacity" value="100"/>
                </bean>
            </property>
        </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    public class UserServiceImpl implements UserService {
        @Resource
        private UserDao userDao;
    
        private AsyncTaskExecutor executor;
        public void setExecutor(AsyncTaskExecutor executor) {
            this.executor = executor;
        }
    
        public void  getUserList() {
            //多线程
            executor.execute(()->{
                System.out.println("========");
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    配置异步@Async

    在applicationContext.xml同目录下创建文件threadPool.xml文件

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:task="http://www.springframework.org/schema/task"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
    
        
        <task:annotation-driven executor="threadPool" />
    
        
        <bean id="threadPool"
              class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
            
            <property name="corePoolSize" value="1000" />
    
            
            <property name="maxPoolSize" value="1000" />
    
            
            <property name="queueCapacity" value="2000" />
    
            
            <property name="keepAliveSeconds" value="300" />
    
            
            <property name="rejectedExecutionHandler">
                
                <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
            property>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    然后后在applicationContext.xml中引入threadPool.xml:

    测试

    定义的异步方法不能与被调用的异步方法在同一个类中,否则无效

    这里模拟取消订单后发短信,有两个发送短信的方法

    @Service
    public class TranTest2Service {
    
    
        // 发送提醒短信 1
        @Async("threadPool")
        public void sendMessage1() throws InterruptedException {
    
            System.out.println("发送短信方法---- 1   执行开始");
            Thread.sleep(5000); // 模拟耗时
            System.out.println("发送短信方法---- 1   执行结束");
        }
    
        // 发送提醒短信 2
        @Async("threadPool")
        public void sendMessage2() throws InterruptedException {
    
            System.out.println("发送短信方法---- 2   执行开始");
            Thread.sleep(2000); // 模拟耗时
            System.out.println("发送短信方法---- 2   执行结束");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    调用发短信的方法

        @Autowired
        private TranTest2Service tranTest2Service;
    
        // 订单处理任务
        @GetMapping(path = "/orderTask")
        public void orderTask() throws InterruptedException {
            tranTest2Service.sendMessage1(); // 发短信的方法   1
            tranTest2Service.sendMessage2(); // 发短信的方法  2
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用@Async效果
    在这里插入图片描述
    不使用@Async效果
    在这里插入图片描述

    基于@Async返回值的调用

    @Async("threadPool")
    public Future<String> asyncMethodWithReturnType() {
        System.out.println("Execute method asynchronously - "
          + Thread.currentThread().getName());
        try {
            Thread.sleep(5000);
            return new AsyncResult<String>("hello world !!!!");
        } catch (InterruptedException e) {
            //
        }
     
        return null;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    以上示例可以发现,返回的数据类型为Future类型,其为一个接口。具体的结果类型为AsyncResult, 这个是需要注意的地方。
    调用返回结果的异步方法示例:

    public void testAsyncAnnotationForMethodsWithReturnType()
       throws InterruptedException, ExecutionException {
        System.out.println("Invoking an asynchronous method. "
          + Thread.currentThread().getName());
        Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();
     	//阻塞全部线程完成后,获取线程返回的内容
    	future.get()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    基于@Async调用中的异常处理机制

    在异步方法中,如果出现异常,对于调用者caller而言,是无法感知的。如果确实需要进行异常处理,则按照如下方法来进行处理:

        <task:annotation-driven executor="exceptionHandlingTaskExecutor"  />
        <bean id="exceptionHandlingTaskExecutor" class=" com.ssm.service.impl.ExceptionHandlingAsyncTaskExecutor">
            <constructor-arg ref="threadPool" />
        bean>
    
    • 1
    • 2
    • 3
    • 4
    public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor {
        private AsyncTaskExecutor executor;
        public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) {
            this.executor = executor;
        }
        //用独立的线程来包装,@Async其本质就是如此
        @Override
        public void execute(Runnable task) {
            executor.execute(createWrappedRunnable(task));
        }
        @Override
        public void execute(Runnable task, long startTimeout) {
            //用独立的线程来包装,@Async其本质就是如此
            executor.execute(createWrappedRunnable(task), startTimeout);
        }
        @Override
        public Future submit(Runnable task) {
            //用独立的线程来包装,@Async其本质就是如此。 
            return executor.submit(createWrappedRunnable(task));
        }
        @Override
        public Future submit(final Callable task) {
            //用独立的线程来包装,@Async其本质就是如此。
            return executor.submit(createCallable(task));
        }
    
        private Callable createCallable(final Callable task) {
            return new Callable() {
                @Override
                public Object call() throws Exception {
                    try {
                        return task.call();
                    } catch (Exception ex) {
                        handle(ex);
                        throw ex;
                    }
                }
            };
        }
    
        private Runnable createWrappedRunnable(final Runnable task) {
            return new Runnable() {
                @Override
                public void run() {
                    try {
                        task.run();
                    } catch (Exception ex) {
                        handle(ex);
                    }
                }
            };
        }
        private void handle(Exception ex) {
            //具体的异常逻辑处理的地方
            System.err.println("Error during @Async execution: " + ex);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在这里插入图片描述

    点赞 -收藏-关注-便于以后复习和收到最新内容
    有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
    在本博客学习的技术不得以任何方式直接或者间接的从事违反中华人民共和国法律,内容仅供学习、交流与参考
    免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我、以迅速采取适当措施,避免给双方造成不必要的经济损失。
    感谢,配合,希望我的努力对你有帮助^_^
  • 相关阅读:
    【Linux】指令详解(二)
    [附源码]计算机毕业设计JAVA鞋店销售管理
    云尘靶场 --铁三域控
    java:操作session
    轧钢切头飞剪机设计及有限元分析
    git clone - error: invalid path
    P4343 [SHOI2015]自动刷题机-二分的两种情况
    以hive metastore报错举例,远程调试hadoop服务
    ScalableViT网络模型
    光伏三相并网逆变器的控制策略与性能分析(Simulink仿真实现)
  • 原文地址:https://blog.csdn.net/weixin_45203607/article/details/126034153