线程池使用不规范导致线程数大以及@Async的规范使用

文章详细内容来自:线程数突增!领导:谁再这么写就滚蛋!

下面是看完后文章的,一个总结

线程池的使用不规范,导致程序中线程数不下降,线程数量大。

临时变量的接口,通过下面简单的线程池执行,

java 复制代码
private static void threadDontGcDemo(){
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.submit(() -> {
            System.out.println("111");
        });
    }

线程不被GC回收,主要是线程池的gc root还是有可达路径的。这里讲个冷知识,这里的线程池的gc root是线程,具体的gc路径是thread->workers->线程池

如果临时采用线程池,需要 手动设置线程池的shutdown,下面写法:

java 复制代码
private static void threadDontGcDemo(){
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.submit(() -> {
            System.out.println("111");
        });
        executorService.shutdown();
    }

原理是,shutdown方法是遍历所有线程,并且调用线程的interrupt()方法,通知线程中断,当worker进行getTask()时,让处于wait的线程打断,抛出异常,workers捕获该worker,workers.remove(w),然后将worker移除workers,这样gc root就不可达了,便会被GC掉。

也就是说线程池的shutdownnow方法调用interruptIdleWorkers去对线程对象interrupt是为了让处于waiting或者是time_waiting的线程抛出异常。

总结为:

  • 线程池调用shutdownnow方法是为了调用worker对象的interrupt方法,来打断那些沉睡中的线程(waiting或者time_waiting状态),使其抛出异常

  • 线程池会把抛出异常的worker对象从workers集合中移除引用,此时被移除的worker对象因为没有到达gc root的路径已经可以被gc掉了

  • 等到workers对象空了,并且当前tomcat线程也结束,此时线程池对象也可以被gc掉,整个线程池对象成功释放

@Async 线程控制

如果不进行线程控制,则异步执行程序越多,会导致线程用尽。

一种方式是全局配置,所有的异步线程共用线程池

java 复制代码
@Configuration
public class AsyncConfig implements AsyncConfigurer {

  @Override
  public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(10);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(100);
    return executor;
  }

     @Override
  public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new CustomAsyncExceptionHandler();
  }

    @Override
    public Integer getAsyncExecutor() {
      return 30; // 单位为秒
    }

}

另外一种是,@Async标签指定使用的线程池名称

java 复制代码
@Configuration
@EnableAsync
public class TaskExcutorConfig {
    @Bean("taskExecutor")
    public Executor taskExecutro() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(30);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(200);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("taskExecutor--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        return taskExecutor;
    }

    @Bean("commonExecutor")
    public Executor commonTaskExecutro() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(50);
        taskExecutor.setMaxPoolSize(100);
        taskExecutor.setQueueCapacity(2000);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("commonExecutor--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        return taskExecutor;
    }

    @Bean("notificationExecutor")
    public Executor notificationExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(30);
        taskExecutor.setMaxPoolSize(60);
        taskExecutor.setQueueCapacity(2000);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("notificationExecutor--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        return taskExecutor;
    }
}

使用时标明:

复制代码
@Async("commonExecutor")
相关推荐
二哈喇子!几秒前
IDEA启动后控制台不报错,但是页面访问404
java·intellij-idea·mybatis
二哈喇子!1 分钟前
Tomcat下载安装以及配置(详细教程)
java·tomcat·intellij-idea
计算机毕设指导62 分钟前
基于微信小程序的健康管理系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
月月玩代码12 分钟前
OkHttp,Square出品的Java/Android HTTP客户端!
android·java·okhttp
胡八一14 分钟前
IntelliJ IDEA 配置插件目录
java·ide·intellij-idea
资生算法程序员_畅想家_剑魔18 分钟前
Java常见技术分享-分布式篇-SpringCloud-01-基础组件
java·分布式·spring cloud
信码由缰20 分钟前
SJF4J 五分钟入门:Java 的实用 JSON 门面
java·python·json
yi诺千金22 分钟前
Android U 自由窗口(浮窗)——操作栏相关
android·java·ui
紫小米24 分钟前
Function calling实践
java·前端·数据库
计算机毕设指导624 分钟前
基于微信小程序的电影评论与推荐社区平台【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea