Java线程池中多余的线程是如何回收的

yizhihongxing

Java线程池可以有效控制线程的数量,提高程序的性能和资源利用率。但是在使用线程池的过程中,我们需要考虑线程池中多余的线程是如何回收的。下面我将从线程池的工作原理、线程池中的线程回收机制两个方面讲解这个问题。

线程池的工作原理

线程池在创建时会预先分配一定数量的线程。当用户提交任务时,线程池就会将任务分配给其中的一个空闲线程执行。如果线程池中没有空闲的线程,那么任务就会进入任务队列等待执行。当一个线程完成了任务后,它会从任务队列中取出下一个任务执行。

线程池中的线程回收机制

线程池中的线程回收机制主要体现在两个方面:空闲线程的回收和超时线程的回收。

1. 空闲线程的回收

线程池中的线程通常分为核心线程和非核心线程。当线程池中的线程数大于核心线程数时,非核心线程就成为了多余的线程。这些多余的线程默认情况下会在经过一定时间后被回收。具体实现方式取决于线程池的实现,可以有如下两种方式:

  1. Java自带的线程池实现类ThreadPoolExecutor采用了一种maxIdleTime为60秒的回收策略。当有线程处于空闲状态超过60秒时,就会被回收。

  2. HikariCP线程池的实现类HikariThreadPoolExecutor采用了一种新的回收策略,称之为熔断策略。当空闲线程存活时间超过maxLifetime时,会进入熔断状态。在熔断状态下,线程的空闲时间不会被计算。只有当线程池中的线程小于核心线程数时,才会回收处于熔断状态的线程。

2. 超时线程的回收

超时线程是指线程执行任务时超过给定时间限制的线程。具体实现方式也有如下的两种:

  1. 在ThreadPoolExecutor中,可以通过设置allowCoreThreadTimeOut参数为true来启动超时线程的回收机制。当一个线程处于空闲状态超过keepAliveTime时间,并且线程池中的线程数量大于corePoolSize,那么这个线程就会被回收。

  2. 在HikariCP线程池中,超时线程的回收机制是通过设置threadTimeout = 30秒实现的。当一个线程执行任务的时间超过30秒时,会被认为超时,线程就会被回收。

示例说明

下面通过两个简单的示例来说明Java线程池中多余的线程是如何回收的。

public class ThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "执行任务完毕");
            });
        }
        executorService.shutdown();
    }
}

上面的示例中,创建了一个具有5个线程的线程池,然后提交了10个任务给线程池执行。由于线程池中的核心线程数为5,非核心线程数为5,因此只有5个线程可以同时执行任务,剩下的5个任务会进入任务队列等待执行。当一个线程完成任务后,它会继续等待下一个任务执行。如果线程空闲时间超过60秒,那么就会被回收。

public class ThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService executorService = new ThreadPoolExecutor(5, 10,
                60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(20),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 30; i++) {
            executorService.execute(() -> {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "执行任务完毕");
            });
        }
        executorService.shutdown();
    }
}

上面的示例中,创建了一个具有5个核心线程和10个最大线程的线程池,超时时间为60秒。提交了30个任务给线程池执行。由于任务执行时间为10秒,因此线程池中只有5个线程可以同时执行任务,剩下的25个任务会进入任务队列等待执行。当线程空闲时间超过60秒时,多余的线程就会被回收。如果在任务执行时超过60秒,那么线程也会被回收。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java线程池中多余的线程是如何回收的 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 21基于java的旅游信息管理系统

    项目背景 根据旅游行业的这种现状,提出解决问题的一个可行性方法,实现了旅游管理的网络化。 项目总体介绍 旅游系统设计分为前后网站和后台管理系统,功能点包含旅游景点信息分类展示、景点详情(地理位置、特色景点概述等)、下单预订等功能;角色分为管理员和普通用户。用户可以对旅游线路及其详细信息进行查询、预定旅游线路等。详细如下: 用户注册,登录 查看和预订旅游路线 …

    Java 2023年5月5日
    00
  • Springboot+hibernate实现简单的增删改查示例

    现在我将详细讲解如何用Springboot和Hibernate实现一个简单的增删改查示例,示例将包括两个部分。 简介 Springboot是一个开源的Java开发框架,可以帮助开发者快速构建高效、可扩展的web应用程序。而Hibernate则是一个Java持久化框架,通过ORM(对象关系映射)的方式来实现对象和关系数据之间的映射。通过结合使用Springbo…

    Java 2023年5月19日
    00
  • springmvc视图解析流程代码实例

    下面我将为大家详细讲解“springmvc视图解析流程代码实例”的完整攻略。 什么是SpringMVC视图解析器? SpringMVC视图解析器指的是一个组件,它用于将控制器返回给客户端的模型数据解析成最终的HTML、JSON、XML等格式的视图响应。在SpringMVC中,视图解析器通常工作在处理器映射器之后,即处理器执行方法之后。 SpringMVC视图…

    Java 2023年6月15日
    00
  • 使用Java将字符串在ISO-8859-1和UTF-8之间相互转换

    首先,我们需要了解一下ISO-8859-1和UTF-8。 ISO-8859-1是一种字符编码,能够表示大部分欧洲语言的字符。在ISO-8859-1中,每个字符占据一个字节,使用1个字节来表示一个字符。然而,ISO-8859-1不能表示非欧洲语言的字符,比如中文、日文等。 而UTF-8则是一种Unicode字符编码,能够表示世界上的所有字符。UTF-8使用1到…

    Java 2023年5月20日
    00
  • Java删除文件、目录及目录下所有文件的方法实例

    下面是关于Java删除文件、目录及目录下所有文件的方法实例的完整攻略: 使用Java的IO模块删除文件和目录 删除文件的方法 在Java中删除文件可以使用Java自带的IO模块中的 File 类的 delete() 方法,该方法将直接删除指定的文件。下面是代码示例: import java.io.File; public class DeleteFileEx…

    Java 2023年5月20日
    00
  • java实现自定义日期选择器的方法实例

    下面我来详细讲解“java实现自定义日期选择器的方法实例”的完整攻略。本攻略分为以下几个部分: 1. 准备工作 在开始实现日期选择器之前,我们需要先准备一些工作。 添加依赖 在项目的gradle文件中,我们需要添加以下依赖: implementation ‘com.squareup.timessquare:library:1.6.5’ 创建布局文件 接着,我…

    Java 2023年5月20日
    00
  • 教你如何在 javadoc 输出<> 符号

    当我们在撰写Java API文档时,有些类和方法的描述中可能涉及到尖括号(<和>)等特殊符号,但是当这些符号在javadoc中直接显示时会被解析为html标签,导致javadoc的显示不正常,影响使用。那么,如何在javadoc中输出这些特殊符号呢?下面是详细攻略: 1. 使用html实体字符 可以使用html实体字符来替代尖括号,其中大于号可用…

    Java 2023年5月26日
    00
  • JVM调优笔记(一)–Nacos GC引发的服务批量下线问题

    故障背景 线上批量发服务下线的告警邮件,偶发nacos连接超时。采用了spring boot admin(以下称sba)进行服务监控。 原因分析 因为sba服务是基于nacos对其它服务进行监控,所以遇到这个问题,第一怀疑对象是nacos发生问题,但不清楚具体是什么问题。由于服务过一段事件会恢复,所以nacos肯定是没有挂掉的,那么排查方向应该是针对naco…

    Java 2023年4月23日
    00
合作推广
合作推广
分享本页
返回顶部