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

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日

相关文章

  • SpringMVC实现RESTful风格:@PathVariable注解的使用方式

    简介 RESTful风格是一种Web服务的设计风格,它使用HTTP协议的GET、POST、PUT、DELETE等方法来实现对资源的操作。SpringMVC提供了一种简单的方式来实现RESTful风格,即使用@PathVariable注解。本文将介绍如何使用@PathVariable注解来实现RESTful风格,并提供两个示例说明。 示例1:获取用户信息 以下…

    Java 2023年5月17日
    00
  • 详解Java数组的一维和二维讲解和内存显示图

    详解Java数组的一维和二维讲解和内存显示图 一维数组 一维数组是一种最简单的数组,它是一组相同类型的变量的有序集合。数组中的每个变量是一个元素,每个元素都有一个唯一的下标。 声明一维数组 声明一维数组的语法如下: type[] arrayName; 其中,type可以是Java中任何一种数据类型。下面是一个声明整数数组的例子: int[] numbers;…

    Java 2023年5月26日
    00
  • jsp 文件上传浏览,支持ie6,ie7,ie8

    实现 JSP 文件上传浏览并支持 IE6, IE7, IE8 可以通过以下步骤实现: 使用 form 表单实现文件上传 JSP 文件上传可以通过 form 表单中的 enctype 属性来实现: <form method="post" enctype="multipart/form-data" action=&q…

    Java 2023年6月15日
    00
  • Java 常量字符串过长的解决方法

    Java 常量字符串过长的解决方法主要包括以下两种方式: 1. 使用换行符 Java中可以使用换行符\将一行代码分成多行,这也适用于字符串常量。可以在字符串过长的地方使用\将字符串分割成多行,从而解决字符串过长的问题。 示例代码: String str = "这是一个非常长的字符串,我们可以在适当的位置使用\"\\\"将它分成多…

    Java 2023年5月26日
    00
  • Spring Boot 使用Druid详解

    Spring Boot使用Druid的详细攻略如下: 添加Druid依赖 在Spring Boot中使用Druid,需要在pom.xml文件中添加Druid的依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot…

    Java 2023年5月15日
    00
  • JS注释所产生的bug 即使注释也会执行

    JS注释所产生的bug是指在一些情况下,即使代码中存在注释,这些注释也会被执行而导致程序出现问题。 该问题主要是因为在一些JS引擎中,被注释的代码可能在编译阶段和解析阶段都会被执行,因此如果注释中包含了有效的代码,则这些代码会被直接执行。这就引起了一定的安全隐患,也可能导致代码出现逻辑错误。 下面通过两个示例来说明该问题: 示例一: function tes…

    Java 2023年6月15日
    00
  • Springboot配置security basic path无效解决方案

    针对“Springboot配置security basic path无效解决方案”,以下是完整的攻略: 1. 问题描述 当我们在Spring Boot项目中将Spring Security集成进来时,有时候会发现配置的basic path无效,即虽然配置了basic path,但在请求时仍然需要登录验证,这种情况该怎么解决呢? 2. 解决方案 2.1 配置W…

    Java 2023年5月20日
    00
  • win7系统打开java的控制面板的方法

    要在Win7系统上打开Java控制面板,可按照以下步骤进行操作: 方法一:使用Windows搜索功能打开Java控制面板 点击Windows系统右下角的“开始”按钮; 在开始菜单中,点击“搜索程序和文件”栏目输入“Java”; 在搜索结果中,找到并点击“Java”选项; 在弹出的Java应用程序窗口中,点击“Java 控制面板”按钮。 示例一: 步骤1:在窗…

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