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日

相关文章

  • Java-方法重载

    方法重载 同一个类中,多个方法的名称相同,但是形参列表不同。 方法重载的形式 同一个类中,方法名称相同、形参列表不同 形参的个数、类型、顺序不同 形参的名称无关 方法重载的调用流程 当程序调用一个重载方法时,编译器会根据参数列表的不同自动匹配最合适的方法,这种机制叫做方法重载的“重载解析”。 根据方法名和参数列表的数量、类型、顺序来寻找匹配调用方法的方法。 …

    Java 2023年5月3日
    00
  • 解析javascript 数组以及json元素的添加删除

    要解析JavaScript数组和JSON元素的添加和删除,我们需要做以下几个步骤: 1. 创建一个数组或JSON对象 首先,我们需要创建一个空的数组或JSON对象。 创建数组 let myArray = []; 创建JSON对象 let myJSON = {}; 2. 向数组或JSON对象中添加元素 添加元素是一种常见的操作,我们可以使用数组的push()方…

    Java 2023年5月26日
    00
  • Java动态循环队列是如何实现的

    Java动态循环队列是一种数据结构,其特点是可以在队列不满时动态修改队列长度,以减小空间的浪费。实现原理是对静态循环队列进行扩容,将队列长度增加为原来的二倍。 以下是Java动态循环队列的实现步骤: 定义静态循环队列的数据结构,包括队列的长度(size)、队首下标(front)、队尾下标(rear)和队列元素(elements)。代码如下: public c…

    Java 2023年5月26日
    00
  • JAVA异常是否对于性能有影响

    Java异常对性能的影响因多种因素而异,例如异常的种类、异常发生的频率、异常处理的方式等等。下面将分别从三个方面介绍Java异常对性能的影响。 异常的种类对性能影响 Java中存在两种异常:受检异常(checked exception)和未受检异常(unchecked exception)。受检异常需要在方法签名中指定,因此在运行时处理受检异常会对性能产生一…

    Java 2023年5月27日
    00
  • JSP 中Servlet的自己实现

    JSP 中Servlet的自己实现 Servlet是Java中常用的服务器端程序,可以接收和处理HTTP请求,并返回相应的 HTTP响应。JSP(Java Server Pages) 是一个动态的Java web页面技术,可以在网页中嵌入 Java 代码片段,用于生成动态内容。 在JSP中使用Servlet,通常有两种方式:一是在JSP页面中直接使用标签引入…

    Java 2023年6月15日
    00
  • java编译时出现使用了未经检查或不安全的操作解决方法

    当在Java开发时,我们可能会遇到以下编译警告: warning: [unchecked] unchecked conversion List<String> uncheckedList = new ArrayList(); ^ required: List<String> found: ArrayList 这个警告通常是由于使用了未…

    Java 2023年5月26日
    00
  • Spring Cloud下OAUTH2注销的实现示例

    让我来详细讲解一下“Spring Cloud下OAUTH2注销的实现示例”的完整攻略。本文将介绍两种实现OAuth2注销的方法。 方法一:使用Spring Security OAuth2自带的注销功能 在使用Spring Security OAuth2时,我们可以使用其自带的注销功能来实现OAuth2注销。具体方法如下: 1.添加注销请求路径 在Spring…

    Java 2023年5月20日
    00
  • JAVA 格式化JSON数据并保存到json文件中的实例

    下面是详细讲解“JAVA 格式化JSON数据并保存到json文件中的实例”的攻略。 1. 引入依赖 在JAVA中对JSON格式化的操作一般使用 GSON 库。在项目中需要先引入 GSON 库的依赖。 Maven依赖: <dependency> <groupId>com.google.code.gson</groupId> …

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