在说核心内容之前,需要问一个问题,既然单个线程的创建和销毁都很简单,我们为什么要使用线程池?
使用池化技术是为了什么?
估计工作过很多年的老鸟们对这些东西都能说出个一二三来,无非就是以下几点:
1、线程相对于进程而言,虽然是轻量级的,但是它的创建依然需要占用我们那点宝贵的内存资源。如果无限制的创建线程,对应垃圾回收而言也是很有压力的,毕竟线程也是对象。使用线程池统一进行线程的调度,便于管理和控制。
2、线程的创建和关闭是需要花费时间的,这点毋庸置疑吧。如果任务非常多,频繁的创建和销毁线程也是需要占用系统的分片时间的,对于系统而言,这点时间对于处理任务的时间来说,有点浪费。
总结一下,使用线程池的目的就是将系统创建的线程进行复用,节约创建和销毁线程带来的时间开销。使用线程池后,创建线程就变成了从线程池获取空闲线程(当然,没有线程的时候也是需要创建的),销毁线程就变成了将线程归还线程池。
创建线程是为了什么?当然是为了处理任务(Task)。
一、JDK对线程池的支持
JDK提供了一套Executor框架,帮助开发人员有效的进行线程控制。
Executor框架结构图(最好自己画个UML类图,首先需要知道类图中每个符号的意思,这是源码必备的分析方法):
以上涉及到的核心成员类都在java.util.concurrent包下。
上图是全部的UML类图关系,猛然一看,估计你不懵都难。所以,我们抛去依赖关系,得到最简图,这样理解起来就不费劲了。
那么,我们说的线程池是谁?就是ThreadPoolExecutor。我学习东西喜欢刨根问底,所以,我想问为什么它就是线程池?我们看上图,所有接口的第一个实现类是谁(不算抽象类)?对头,就是ThreadPoolExecutor。ScheduledThreadPoolExecutor扩展了线程池的功能(为什么英文起名字要见名知意,你从Scheduled是不是明白了什么),可以把它作为扩展功能了解。
以上整个代码架构,有人称之为Executor框架(不要一听框架就觉得有多么神奇高大,它就是个名字,因为线程池的一整套代码组织的起源是Executor,往上看下)。
二、线程池详解
既然要深究线程池,就不得不去看看源码,毕竟源码才是作者表达意思的代码体现。
我们看下线程池有些什么玩意--我们追踪了这个类中的实现,所有的构造函数,无一例外的都归结到下面最长的这个构造函数上,也就是说,这个构造函数是线程池的核心!
/** * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial * parameters. * * @param corePoolSize the number of threads to keep in the * pool, even if they are idle. * @param maximumPoolSize the maximum number of threads to allow in the * pool. * @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating. * @param unit the time unit for the keepAliveTime * argument. * @param workQueue the queue to use for holding tasks before they * are executed. This queue will hold only the <tt>Runnable</tt> * tasks submitted by the <tt>execute</tt> method. * @param threadFactory the factory to use when the executor * creates a new thread. * @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached. * @throws IllegalArgumentException if corePoolSize or * keepAliveTime less than zero, or if maximumPoolSize less than or * equal to zero, or if corePoolSize greater than maximumPoolSize. * @throws NullPointerException if <tt>workQueue</tt> * or <tt>threadFactory</tt> or <tt>handler</tt> are null. */ public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
我们详细解释下这些参数的含义:
看参数含义,我们最好不要自己去理解,看的时候要结合英文注释,因为注释部分是作者要表达的真正含义。
①corePoolSize: the number of threads to keep in the pool, even if they are idle.(核心线程池大小:为什么这么起名称,是因为作者想表达的含义是线程池应该保证线程数目会有这么多,不管他们创建以后是不是空闲)。
②maximumPoolSize: the maximum number of threads to allow in the pool.(线程池中允许创建线程的最大数目,啥意思?如果核心线程数已经达到,任务还源源不断的来,那么maximumPoolSize表达的意思就是核心线程数+新创建的线程数据<=最大线程数目)。
③keepAliveTime:when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.(超过核心线程数的线程,在新任务到来之前能存活的最长时间,如果没等到,那么它就拜拜了)
④unit: the time unit for the keepAliveTime argument.(就是keepAliveTime 参数的单位)
⑤BlockingQueue<Runnable> workQueue:the queue to use for holding tasks before they are executed. This queue will hold only the <tt>Runnable</tt> tasks submitted by the <tt>execute</tt> method.(等待执行的任务队列,它的作用就是用来存放还没有被执行的任务。这个队列仅仅用来存放被execute方法提交的Runnable任务,不要翻译成工作队列,那是给自己找麻烦)
⑥threadFactory:the factory to use when the executor creates a new thread.(线程工厂,用来创建新线程的工厂,一般使用默认工厂--Executors.defaultThreadFactory(),它是Executors类中的一个静态内部类的方法,返回一个实体类DefaultThreadFactory)
⑦RejectedExecutionHandler handler: the handler to use when execution is blocked because the thread bounds and queue capacities are reached.(当任务队列中任务已经达到了等待执行任务的队列的大小[有界队列会出现]时,要采取什么样的处理(handler)方式,取名叫拒绝策略,就是我应该怎么抛弃你)
下一篇,我们详细介绍下BlockingQueue<Runnable> 常用的等待执行任务存放的队列和RejectedExecutionHandler常用的任务拒绝策略。
相关推荐
### Java多线程并发知识点详解 #### 一、Java多线程并发简介 在现代软件开发中,特别是在Java这样的主流编程语言中,多线程并发技术是提高程序执行效率、优化资源利用的关键手段之一。本篇文章将深入探讨Java中的...
以上是对"Java多线程详解"主题的详细阐述,涵盖了Java多线程的基本概念、实现方式、线程控制、线程池、并发集合、线程间通信以及并发编程中常见的问题和解决方案。学习和熟练掌握这些内容对于开发高效的多线程Java...
标题《Java多线程编程深入详解》所涉及的知识点涵盖了Java多线程编程的核心思想、原理以及在实际开发中可能遇到的问题和解决方案。以下是对这些知识点的详细阐述: 1. 多进程与多线程概念的区分和理解 - 进程是...
内容概要:本文详细介绍了 Java多线程编程的基础知识和高级技术。内容涵盖线程的概念与重要性、创建线程的方式、线程的生命周期与基本控制方法、线程同步与死锁、线程间通信、线程池与 Executor框架、并发集合与原子...
Java多线程高级设计模式详解 在Java编程中,多线程是不可或缺的一部分,它能够充分利用多核处理器的计算能力,提高程序的并发性能。本文将深入探讨Java多线程中的高级设计模式,帮助开发者更好地理解和应用这些模式...
总之,Java多线程是构建高性能并发应用的基础,理解并掌握线程的创建、同步、通信、协作模式以及异常处理,对于编写高效、稳定的Java程序至关重要。在实际开发中,结合Java提供的工具和设计模式,能够更好地解决多...
### JAVA高质量并发详解知识点概述 #### 一、Java并发编程基础 - **基础知识:** - **线程基本概念:** Java线程是程序执行流的最小单元,一个线程包含一个程序计数器(PC)、虚拟机栈、本地方法栈、线程私有的工作...
在Java编程领域,分布式多线程中间件是高级主题,涉及到复杂的系统设计和优化。本教程合集将深入探讨这些核心概念,旨在帮助开发者提升技能并应对大型、高并发的应用场景。 首先,让我们来理解“Java高级教程”的...
### Java多线程文章系列知识点概述 #### 一、Java多线程编程...以上是《Java多线程文章系列》的主要知识点概述,涵盖了从多线程的基础概念到高级应用,希望能帮助读者深入理解Java多线程编程的核心技术和实践技巧。
多线程与线程池是Java编程中至关重要的概念,特别是在处理高并发场景时,它们的作用尤为突出。本文将深入探讨这两个主题,并结合标签中的"排它锁"、"重入锁"、"共享锁"等概念进行讲解。 首先,线程是操作系统分配...
Java多线程设计模式是Java开发中不可或缺的一部分,它涉及到并发编程、系统性能优化以及程序的稳定性。在Java中,多线程可以提高程序的执行效率,通过将任务分解到多个独立的执行线程,使得程序能同时处理多个任务。...
### Java多线程详解:掌握核心概念与编程技巧 #### 一、线程与线程类:理解基础概念 在Java编程中,多线程是一个关键特性,它允许在单个程序中并发执行多个线程,从而提高程序的效率和响应性。线程,作为进程内的...
### Java多线程编程知识点详解 #### 一、线程基础概述 - **定义与特点:** - **线程**是一种比进程更细粒度的执行单元,它允许在一个进程中并发执行多个任务。 - **轻量级进程**:线程有时被称为轻量级进程,...
Java多线程和并发知识是Java开发...以上内容涵盖了Java多线程和并发编程的主要知识点,从理论到实践,从基础到高级,全面解析了并发编程的核心概念和工具。掌握这些知识,开发者可以编写出高效、可靠的多线程应用程序。
《Java高并发程序设计》是一本深入探讨Java平台上的并发编程技术的专业书籍,由葛一鸣等人编著。这本书旨在帮助读者理解并掌握在高并发环境下编写高效、稳定且可扩展的Java应用程序的关键技巧和最佳实践。以下是该书...
Java多线程设计模式是Java开发中不可或缺的一部分,它涉及到并发编程的核心理论和技术。在Java中,多线程用于提高程序的执行效率,通过同时执行多个任务来利用系统资源。本资料包包含“java多线程设计模式详解”文档...
在"JAVA多线程编程详解-详细操作例子.doc"和"Java多线程编程详解.doc"文档中,你应该能找到关于以上知识点的具体示例和深入解释,包括如何创建线程、线程间的通信(如wait/notify机制、Semaphore、CountDownLatch)...
3. **提高系统响应速度**:使用线程池可以避免每次创建和销毁线程所花费的时间,尤其是在高并发场景下,这种优化效果尤为明显。 #### 三、线程池的优势 - **任务执行效率提升**:减少了线程创建和销毁的开销,使得...
通过对这些知识点的学习,读者可以全面掌握Java并发编程的核心技术和最佳实践,为开发高性能、高可靠性的并发应用程序打下坚实的基础。无论是初学者还是有经验的开发者,都能从本书中获得宝贵的知识和技能。