线程池ThreadPoolExecutor分析: 线程池是什么时候创建线程的,队列中的任务是什么时候取出来的?

带着几个问题进入源码分析:

线程池是什么时候创建线程的?

任务runnable task是先放到core到maxThread之间的线程,还是先放到队列?

队列中的任务是什么时候取出来的?

什么时候会触发reject策略?

core到maxThread之间的线程什么时候会die?

task抛出异常,线程池中这个work thread还能运行其他任务吗?

至少在new ThreadPoolExecutor()时,Thread对象并没有初始化. 这里仅仅指定了几个初始参数

一段基础代码,进入分析

public static void main(String[] args) {

        ExecutorService executorService = new ThreadPoolExecutor(2, 5, 0, TimeUnit.DAYS,
                new ArrayBlockingQueue<>(1), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
//                thread.setDaemon(true);
                return thread;
            }
        });
        // 对象创建后,线程实际还没开始创建

        // 执行execute时,检查当前池中线程数大小是否小于core number, 如果是,则创建新线程
        executorService.execute(() -> {
            System.out.println("[email protected]" + Thread.currentThread().getName());
            sleepTime();
            System.out.println(1);
        });

        //检查当前池中线程数大小是否小于core number, 如果是,则创建新线程
        executorService.execute(() -> {
            System.out.println("[email protected]" + Thread.currentThread().getName());
            sleepTime();
            System.out.println(2);
        });

        // 检查当前池中线程数大小是否小于core number, 如果不是,则偿试放入队列
        // 这个任务是加到队列去的, 注意队列大小只有1,
        // TODO 队列中的任务是什么时候取出来的?
        executorService.execute(() -> {
            System.out.println("[email protected]" + Thread.currentThread().getName());
            sleepTime();
            System.out.println(3);
        });

        // 检查当前池中线程数大小是否小于core number, 如果不是,则偿试放入队列,放入队列也失败,则增加新的worker线程
        // 这个任务是加到core以外的新线程去的
        executorService.execute(() -> {
            System.out.println("[email protected]" + Thread.currentThread().getName());
            sleepTime();
            System.out.println(4);
        });
    }

  

第3行,创建一个核心池2, 最大池5, 队列为1的线程池

执行第一个execute时,进入调试jdk源码

代码块1

第一个if, 判断如果当前线程数小于corePoolSize, 则创建新的核心worker对象(Worker中指向Thread对象,保持引用,保证不会被GC回收)

我们的示例代码中,第1和第2个线程都是这样创建出线程的

原文地址:https://www.cnblogs.com/yszzu/p/10122658.html

时间: 2024-11-09 12:17:30

线程池ThreadPoolExecutor分析: 线程池是什么时候创建线程的,队列中的任务是什么时候取出来的?的相关文章

线程池ThreadPoolExecutor分析

线程池.线程池是什么,说究竟,线程池是处理多线程的一种形式,管理线程的创建,任务的运行,避免了无限创建新的线程带来的资源消耗,可以提高应用的性能.非常多相关操作都是离不开的线程池的,比方android应用中网络请求的封装.这篇博客要解决的问题是: 1.线程池的工作原理及过程. 要分析线程池的工作原理及过程,还是要从它的源代码实现入手,首先是线程是构造方法,何谓构造方法.构造方法就是对成员变量进行初始化,在这里,我们能够看到它的构造方法: /** * Creates a new {@code Th

线程池ThreadPoolExecutor、Executors参数详解与源代码分析

欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. ThreadPoolExecutor数据成员 Private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING,0)); ctl主要用于存储线程池的工作状态以及池中正在运行的线程数.显然要在一个整型变量存储两个数据,只能将其一分为二.其中高3bit用于存储线程池的状态,低位的29bit用于存储正在运行的线程数. 线

JDK源码分析之concurrent包(二) -- 线程池ThreadPoolExecutor

上一篇我们简单描述了Executor框架的结构,本篇正式开始并发包中部分源码的解读. 我们知道,目前主流的商用虚拟机在线程的实现上可能会有所差别.但不管如何实现,在开启和关闭线程时一定会耗费很多CPU资源,甚至在线程的挂起和恢复JDK1.6都做了自旋锁的优化.所以,使用线程池来管理和执行多线程任务会大大提高程序执行效率.关于使用线程池的优点这里不做过多说明,我们直接进入Java5并发包中ThreadPoolExecutor的实现的源码. 在解读源码前,我们先来看看创建线程池的一般做法和线程池的几

【Java并发编程】21、线程池ThreadPoolExecutor源码解析

一.前言 JUC这部分还有线程池这一块没有分析,需要抓紧时间分析,下面开始ThreadPoolExecutor,其是线程池的基础,分析完了这个类会简化之后的分析,线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法.下面开始分析. 二.ThreadPoolExecutor数据结构 在ThreadPoolExecutor的内部,主要由BlockingQueue和AbstractQu

线程池ThreadPoolExecutor源码解读研究(JDK1.8)

一.什么是线程池 为什么要使用线程池?在多线程并发开发中,线程的数量较多,且每个线程执行一定的时间后就结束了,下一个线程任务到来还需要重新创建线程,这样线程数量特别庞大的时候,频繁的创建线程和销毁线程需要一定时间而且增加系统的额外开销.基于这样的场景,线程池就出现了,线程池可以做到一个线程的任务处理完可以接受下一个任务,并不需要频繁的创建销毁,这样大大节省了时间和系统的开销. 线程池,顾名思义,就是一个池子,任务提交的到线程池后,线程池会在池子里边找有没有空闲的线程,如果没有,就会进入等待状态,

高并发之——从源码角度分析创建线程池究竟有哪些方式

前言 在Java的高并发领域,线程池一直是一个绕不开的话题.有些童鞋一直在使用线程池,但是,对于如何创建线程池仅仅停留在使用Executors工具类的方式,那么,创建线程池究竟存在哪几种方式呢?就让我们一起从创建线程池的源码来深入分析究竟有哪些方式可以创建线程池. 使用Executors工具类创建线程池 在创建线程池时,初学者用的最多的就是Executors 这个工具类,而使用这个工具类创建线程池时非常简单的,不需要关注太多的线程池细节,只需要传入必要的参数即可.Executors 工具类提供了

java线程API学习 线程池ThreadPoolExecutor(转)

线程池ThreadPoolExecutor继承自ExecutorService.是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行. 构造函数 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, Rejected

应用线程池ThreadPoolExecutor

线程池的大小 在配置和调整应用线程池的时候,首先考虑的是线程池的大小. 线程池的合理大小取决于未来提交的任务类型和所部署系统的特征.定制线程池的时候需要避免线程池的长度"过大"或者"过小"这两种极端情况. 线程池过大:那么线程对稀缺的CPU和内存资源的竞争,会导致内存高使用量,还可能耗尽资源. 线程池过小:由于存在很多可用的处理器资源还未工作,会对吞吐量造成损失. 精密的计算出线程池的确切大小是很困难的,一般我们会估算出一个合理的线程池大小. 对于计算密集型任务,一

多线程(十七、深入了解线程池-ThreadPoolExecutor)

ThreadPoolExecutor原理 ThreadPoolExecutor构造函数参数 /** * 使用给定的参数创建ThreadPoolExecutor. * * @param corePoolSize 核心线程池中的最大线程数 * @param maximumPoolSize 总线程池中的最大线程数 * @param keepAliveTime 空闲线程的存活时间 * @param unit keepAliveTime的单位 * @param workQueue 任务队列, 保存已经提交