java线程池中线程数量到底是几

首先让我们来了解一下Java线程池。

线程池是一种线程使用方式的抽象,它可以优化多线程的资源使用情况。通过重复利用已创建的线程,降低线程创建和销毁的开销,提高响应速度。

而Java中的线程池主要由ThreadPoolExecutor类实现,该类有以下构造方法

public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
                              int maximumPoolSize, //最大线程池大小
                              long keepAliveTime, //线程生存时间
                              TimeUnit unit, //时间单位
                              BlockingQueue<Runnable> workQueue, //任务队列
                              ThreadFactory threadFactory, //线程工厂
                              RejectedExecutionHandler handler) //异常处理器

接下来我们来解答问题:Java线程池中线程数量到底是几

线程池中的线程数量实际上是动态变化的,它由核心线程池大小(corePoolSize)、最大线程池大小(maximumPoolSize)、任务队列(workQueue)等参数共同决定。

具体来说,线程池中线程数量受以下几个条件制约:

  1. 当线程池中运行的线程数小于corePoolSize时,新加入的任务会创建一个新的线程来执行任务,并将该线程放入线程池中,因此线程池中运行的线程数就会增加。

  2. 当线程池中运行的线程数达到corePoolSize时,新加入的任务会被加入到任务队列(workQueue)中等待执行,在任务队列中等待的任务不会立即执行。

  3. 如果任务队列已满,且当前线程池中的线程数小于maximumPoolSize,则线程池会创建一个新的线程来执行任务,因此线程池中运行的线程数就会增加。

  4. 如果当前线程池中运行的线程数已经达到了maximumPoolSize,且任务队列中已经有任务在等待执行,此时线程池会使用RejectedExecutionHandler处理器对任务进行处理,如使用AbortPolicy则会抛出RejectedExecutionException异常,表示任务无法处理。

示例1:

ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
for(int i=0;i<50;i++){
    executor.execute(new Runnable(){
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" is running!");
        }
    });
    System.out.println("Current pool size: "+executor.getPoolSize()+" ,Queue size: "+executor.getQueue().size());
}
executor.shutdown();

在这个示例中,我们创建了一个核心线程池大小为10,最大线程池大小为20的线程池。

我们向线程池中提交了50个任务,每个任务只是输出当前线程的名称。

控制台输出如下:

Current pool size: 1 ,Queue size: 0
Current pool size: 2 ,Queue size: 0
Current pool size: 3 ,Queue size: 0
Current pool size: 4 ,Queue size: 0
Current pool size: 5 ,Queue size: 0
Current pool size: 6 ,Queue size: 0
Current pool size: 7 ,Queue size: 0
Current pool size: 8 ,Queue size: 0
Current pool size: 9 ,Queue size: 0
Current pool size: 10 ,Queue size: 0
Current pool size: 10 ,Queue size: 1
Current pool size: 10 ,Queue size: 2
Current pool size: 10 ,Queue size: 3
Current pool size: 10 ,Queue size: 4
Current pool size: 10 ,Queue size: 5
Current pool size: 10 ,Queue size: 6
Current pool size: 10 ,Queue size: 7
Current pool size: 10 ,Queue size: 8
Current pool size: 10 ,Queue size: 9
Current pool size: 10 ,Queue size: 10
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@603c5a11 rejected from java.util.concurrent.ThreadPoolExecutor@27c170f0[Running, pool size = 10, active threads = 10, queued tasks = 10, completed tasks = 0]

我们可以看到,在任务提交的前10个任务,线程池中都会创建一个新的线程来执行任务,线程池中最大线程数量不会超过10。

当任务队列已经满时,线程池中运行的线程数量已经达到了10个(corePoolSize大小),此时新加入的任务将会被拒绝执行。

示例2:

ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
for(int i=0;i<30;i++){
    executor.execute(new Runnable(){
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" is running!");
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    System.out.println("Current pool size: "+executor.getPoolSize()+" ,Queue size: "+executor.getQueue().size());
}
executor.shutdown();

在这个示例中,我们提交了30个任务,每个任务会输出当前线程名称并休眠1秒钟。

通过设置线程池的CallerRunsPolicy处理器,当线程池被拒绝执行时,该处理器会让当前线程执行任务。

控制台输出如下:

Current pool size: 1 ,Queue size: 0
Current pool size: 2 ,Queue size: 0
Current pool size: 3 ,Queue size: 0
Current pool size: 4 ,Queue size: 0
Current pool size: 5 ,Queue size: 0
Current pool size: 6 ,Queue size: 0
Current pool size: 7 ,Queue size: 0
Current pool size: 8 ,Queue size: 0
Current pool size: 9 ,Queue size: 0
Current pool size: 10 ,Queue size: 0
Current pool size: 10 ,Queue size: 1
Current pool size: 10 ,Queue size: 2
Current pool size: 10 ,Queue size: 3
Current pool size: 10 ,Queue size: 4
Current pool size: 10 ,Queue size: 5
pool-1-thread-12 is running!
Current pool size: 10 ,Queue size: 6
pool-1-thread-13 is running!
Current pool size: 10 ,Queue size: 7
pool-1-thread-14 is running!
Current pool size: 10 ,Queue size: 8
pool-1-thread-15 is running!
Current pool size: 10 ,Queue size: 9
pool-1-thread-16 is running!
Current pool size: 10 ,Queue size: 10
pool-1-thread-17 is running!
pool-1-thread-1 is running!
pool-1-thread-2 is running!
pool-1-thread-3 is running!
pool-1-thread-4 is running!
pool-1-thread-5 is running!
pool-1-thread-6 is running!
pool-1-thread-7 is running!
pool-1-thread-8 is running!
pool-1-thread-9 is running!
pool-1-thread-10 is running!
pool-1-thread-11 is running!

我们可以看到,在任务提交的前10个任务,线程池中都会创建一个新的线程来执行任务,线程池中最大线程数量不会超过10。

当任务队列已经满时,线程池中运行的线程数量已经达到了10个(corePoolSize大小),后续任务被拒绝执行,但是使用了CallerRunsPolicy处理器,当前线程(main线程)执行了被拒绝的任务。

综上所述,Java线程池中线程数量实际上是动态变化的,受多个因素的制约。我们应该根据实际情况进行合理的配置。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java线程池中线程数量到底是几 - Python技术站

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

相关文章

  • 使用JSP读取客户端信息

    使用JSP读取客户端信息需要用到内置对象request,通过request对象的方法获取到客户端的相关信息。 以下是具体的步骤: 在JSP页面中,使用内置对象request获取客户端信息前,需要获取参数request对象。获取的方式是: <% request = request.getRequest(); %> 获取客户端IP地址 <% S…

    Java 2023年6月15日
    00
  • Spring Security 过滤器注册脉络梳理

    Spring Security 是 Spring 框架的子项目,专门用于处理认证与授权相关的安全问题。在 Spring Security 的实现过程中,过滤器是一个核心概念,所有认证和授权都是通过过滤器实现的。因此,了解 Spring Security 过滤器的注册脉络对于学习 Spring Security 至关重要。 Spring Security 过滤…

    Java 2023年6月3日
    00
  • JavaWeb开发使用Cookie创建-获取-持久化、自动登录、购物记录、作用路径

    针对JavaWeb开发中关于Cookie的创建、获取和持久化、自动登录、购物记录、作用路径等问题,下面是一个完整的攻略: 什么是Cookie 在Web开发中,Cookie是存储于客户端的一种数据,它允许Web服务器向客户端的浏览器发送HTTP响应,在浏览器中存储这些数据,而之后浏览器向同一个域发送请求时会自动携带相关的Cookie数据,以此实现数据持久化。 …

    Java 2023年6月16日
    00
  • Java开发者就业需要掌握的9大专业技能

    关于Java开发者就业需要掌握的9大专业技能,我们可以从以下几点展开讲解: 1. Java基础知识 Java基础知识是Java开发者必须掌握的基础技能之一。包括基本的语法、面向对象的特性、集合框架、异常处理、多线程等。只有深入理解Java语言的基本机制,才能为后续的高级知识打下牢固的基础。 示例:如何实现一个简单的Java程序?请编写一个Hello Worl…

    Java 2023年5月20日
    00
  • JSP实用教程之简易文件上传组件的实现方法(附源码)

    让我来详细讲解一下“JSP实用教程之简易文件上传组件的实现方法(附源码)”的完整攻略。 什么是文件上传组件? 文件上传组件通常用于在网站上让用户上传文件,如图片、文档等。在JSP中,我们可以通过一些Java类和第三方库来实现上传功能。而本文将讲解一个简易的文件上传组件的实现方法。 实现步骤 在JSP页面中添加表单、输入框和上传按钮。 <form met…

    Java 2023年6月15日
    00
  • 用JavaScript实现仿Windows关机效果

    当我们尝试模仿操作系统的某些效果时,如Windows关机效果,我们需要使用 JavaScript 和 CSS。下面是实现仿Windows关机效果的完整攻略。 准备工作 在开始实现之前,需要先准备好以下三个工具: 一个编辑器,如 Visual Studio Code 一个浏览器,如 Chrome 一段用于实现效果的HTML和CSS代码 实现过程 以下是实现该效…

    Java 2023年6月16日
    00
  • OpenCV Java实现人脸识别和裁剪功能

    OpenCV Java实现人脸识别和裁剪功能 介绍 OpenCV 是一个跨平台的计算机视觉库,提供了用于图像和视频处理的开放源代码算法。本文将介绍如何使用 OpenCV Java 实现人脸识别和裁剪功能。人脸识别是计算机视觉中的一个重要问题,以其应用广泛而闻名。 安装 在进行开发之前,我们需要安装 OpenCV 和 Java SDK。OpenCV 的安装包可…

    Java 2023年5月20日
    00
  • jsp分页显示的实现代码

    那我就来为大家详细讲解一下JSP分页显示的实现代码的完整攻略。 1. 实现分页的前提条件 在使用JSP实现分页显示前,我们需要先了解一下实现的前提条件。这里列出了两点: 数据库的分页查询:在获取数据时,需要使用数据库的分页查询功能,比如MySQL中的LIMIT语句; JSP中的JavaBean:在JSP中,使用JavaBean来封装分页数据,显示到JSP页面…

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