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

yizhihongxing

首先让我们来了解一下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日

相关文章

  • springboot的缓存技术的实现

    下面我就详细讲解“springboot的缓存技术的实现”的完整攻略。 什么是springboot的缓存技术 springboot是一款非常流行的Java开发框架,其提供了很多缓存技术的支持,这些技术可以帮助我们提高应用程序的性能。 在springboot中,我们可以通过使用缓存注解来实现缓存技术。缓存注解可以帮助我们在方法调用时自动缓存方法的返回值,从而实现…

    Java 2023年5月15日
    00
  • Spring Boot 如何自定义返回错误码错误信息

    一、背景知识 在开发过程中,定义一套统一的错误码以及错误信息对于后续的使用和协作有很大的帮助,这笔帮助在项目人员的交流、定位问题、维护代码等方面会发挥至关重要的作用。 Spring Boot 是一个优秀的开源框架,同样也提供了很多途径来自定义错误码以及错误信息,因此本文打算讲解一下如何在 Spring Boot 中自定义返回错误码和错误消息的过程。 二、应用…

    Java 2023年5月27日
    00
  • Java集合List与Array的相互转换

    下面就为你详细讲解Java集合List与Array的相互转换。 List转Array 1.使用toArray()方法 将List转为数组最简单的方式就是使用List提供的toArray()方法。该方法返回一个持有此列表元素的数组。 List<String> list = new ArrayList<>(); list.add(&quo…

    Java 2023年5月26日
    00
  • java实现2048小游戏(含注释)

    Java实现2048小游戏(含注释)–完整攻略 一、实现思路 绘制游戏界面 完成键盘监听事件,监测用户按键,向左移动、向右移动、向上移动、向下移动 随机生成数字2或4 判断游戏是否结束,判断游戏是否胜利 将游戏界面进行优化 统计游戏分数 二、实现细节 1. 绘制游戏界面 2048的游戏界面是一个4×4的矩阵,我们需要用JPanel布局来实现。将该矩阵分成1…

    Java 2023年5月18日
    00
  • Spring Security验证流程剖析及自定义验证方法

    接下来我将详细讲解“Spring Security验证流程剖析及自定义验证方法”的完整攻略。 1. Spring Security验证流程剖析 1.1 Spring Security简介 Spring Security是Spring框架的一个子项目,提供了基于Acegi Security(一款强大而且全面的开源安全框架)的安全处理功能,它能够为我们的应用程序…

    Java 2023年5月20日
    00
  • 5分钟让你快速掌握java8 stream常用开发技巧

    5分钟让你快速掌握java8 stream常用开发技巧 什么是Stream Java 8引入Stream这个API是为了简化集合操作。Stream可以使用filter、map、reduce等方法对集合进行处理。在操作集合时,Stream会把操作分为中间操作和终止操作两种。中间操作用于筛选和转换数据,终止操作用来搜集数据。Stream不改变原来的集合数据,而是…

    Java 2023年5月26日
    00
  • SpringBoot整合TKMyBatis实现单表增删改查操作

    下面将详细讲解“SpringBoot整合TKMyBatis实现单表增删改查操作”的完整攻略。 1. 导入依赖 首先,在项目的 pom.xml 文件中导入以下依赖: <!– SpringBoot Starter –> <dependency> <groupId>org.springframework.boot</g…

    Java 2023年6月15日
    00
  • Spring BOOT AOP基础应用教程

    Spring BOOT AOP基础应用教程 Spring AOP(面向切面编程)是Spring框架的一个重要组成部分,它可以帮助我们更好地管理和维护代码。在本文中,我们将介绍Spring Boot AOP的基础知识和应用方法。 步骤一:添加依赖 我们需要在pom.xml文件中添加Spring AOP的依赖。以下是一个示例: <dependency&gt…

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