zoukankan      html  css  js  c++  java
  • SpringBoot项目中@Async方法没有执行的问题分析

    现象: 
        1. 表面现象: 方法中输出的日志, 日志文件中找不到, 也没有任何报错(即@Async标注的方法没有执行, 也没有报错)
        2. 分析现象: 日志中某个时刻之后没有了task-xxx线程的日志
     
    原因: 
        @Async异步方法默认使用Spring创建ThreadPoolTaskExecutor(参考TaskExecutionAutoConfiguration), 
    其中默认核心线程数为8, 默认最大队列和默认最大线程数都是Integer.MAX_VALUE. 创建新线程的条件是队列填满时, 而
    这样的配置队列永远不会填满, 如果有@Async注解标注的方法长期占用线程(比如HTTP长连接等待获取结果), 
    在核心8个线程数占用满了之后, 新的调用就会进入队列, 外部表现为没有执行.

    解决:
        手动配置相应属性即可. 比如
        spring.task.execution.pool.queueCapacity=4
        spring.task.execution.pool.coreSize=20

    备注: 
        此处没有配置maxSize, 仍是默认的Integer.MAX_VALUE. 如果配置的话, 请考虑达到最大线程数时的处理策略(JUC包查找RejectedExecutionHandler的实现类)
        (默认为拒绝执行AbortPolicy, 即抛出异常)
        
        AbortPolicy: 直接抛出java.util.concurrent.RejectedExecutionException异常
        CallerRunsPolicy: 主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度
        DiscardOldestPolicy: 抛弃旧的任务
        DiscardPolicy: 抛弃当前任务
        
    截图:
        1. ThreadPoolTaskExecutor
        2. SpringMonitor的配置属性
        3. SpringMonitor的Threads

     

  • 相关阅读:
    IIS7配置URL Rewrite链接重写
    wordpress导航菜单的链接支持弹出新页面
    c++绝对是拯救了世界,特别是程序员
    Linux 磁盘坏道检测和修复
    centos里mysql无法用localhost连接的解决方法
    php扩展开发
    IP多播
    因特网的路由选择协议
    ICMP协议
    ARP协议
  • 原文地址:https://www.cnblogs.com/hepengju/p/12715034.html
Copyright © 2011-2022 走看看