1.线程池介绍

    线程池是一种线程使用模式。线程由于具有空闲(eg:等待返回值)和繁忙这种不同状态,当数量过多时其创建、销毁、调度等都会带来开销。线程池维护了多个线程,当分配可并发执行的任务时,它负责调度线程执行工作,执行完毕后线程不关闭而是返回线程池,可以执行后续其他任务。举例来说,外卖餐厅对每个订单分配一个临时工,完成订单立刻辞退,成本和管理开销巨大,而且如果取餐点的空间有限,大量的人挤满在那反而会影响工作效率,因此选择签下固定数量的外卖小哥让他们不断往返于目的地和店家之间配送。

通俗来讲,线程池就是为了减少开销而复用线程,实现了任务内容和线程分离的一种机制。如果机器有100核而且其他资源充足,直接启动100个无冲突的并发线程应该是比使用线程池要快,但是受限于目前的硬件能力,线程池就很有必要了。Java的Executor框架用于执行异步任务,方法 executor(Runnable runnable) 可以接收Runnable对象。Executor有一个子类接口ExecutorService,提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行状况返回Future的方法。

2.工厂模式创建线程池

Excutors运用工厂模式提供线程池实现方式,返回ExecutorService

  1. newSingleThreadExecutor,单线程的线程池,实际上是串行执行任务,如果该线程出现异常则会有新线程替代它工作,其优势是任务会按照提交顺序执行。

  2. newFixedThreadPool,固定大小线程池,每次新提交任务时如果线程数没达到最大就创建新线程执行任务,否则任务进入等待状态。

  3. newCachedThreadPool,可缓存的线程池,大小依赖于操作系统(JVM)最大值。线程池大于任务数时回收部分空闲(60s)线程,任务数增加时添加新线程。

问题在于,前两者请求处理队列的堆积会消耗内存,第三个创建过多线程也会这样。同时,拒绝策略在Executors中无效。

3.自定义创建

ThreadPoolExecutor是线程池的实现方法签名:

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) //后两个参数为可选参数
  1. corePoolSize,核心线程数,同时处于执行状态的线程最大值(或者说,接单配送中的小哥人数上限)。当线程数少于该值时,新的任务会创建新的线程执行。allowCoreThreadTimeOut属性不设置为true(默认false)时,闲置的核心线程也不会销毁。
  2. maximumPoolSize,线程总数,等于核心线程+非核心线程数,不小于核心线程数。
  3. keepAliveTime,线程进入不活跃状态后到销毁前的时间,通过Unit参数设置单位。通常只适用于非核心线程,allowCoreThreadTimeOut为true时核心线程也适用。
  4. workQueue,任务队列,当核心线程满时新任务进入该队列等待,当队列满时创建非核心线程执行任务。
    • SynchronousQueue:等于没有队列,任何任务都直接给线程处理,为防止线程数量达到最大值,通常设置maximumPoolSize为Integer.MAX_VALUE
    • LinkedBlockingQueue:无限长阻塞队列,总线程数永远等于核心线程数,未执行的任务都在队列里排队
    • ArrayBlockingQueue:定长队列,队列满时新建非核心线程,达到maximumPoolSize后出错
    • DelayQueue,当任务实现Delayed接口时,任务入队等待到指定延时后开始执行
  5. threadFactory,线程工厂
  6. handler,任务被拒绝时的策略
    • AbortPolicy,默认策略,将抛出RejectExecutorException
    • CallerRunsPolicy,线程池未关闭时调用线程(任务提交者)直接执行该任务
    • DiscardPolicy,直接丢弃不抛出异常
    • DiscardOldestPolicy,丢弃队列最前的任务后重试当前任务

4.生命周期

ExecutorService的生命周期包括了运行、关闭和终止三种状态,在初始化创建时处于运行状态。使用submit方法执行Runnable或者Callable对象。shutdown方法等待提交的任务执行完成并不再接受新任务,在完成全部提交的任务后关闭;shutdownNow方法将强制终止所有运行中的任务并不再允许提交新任务。

Java基础学习——多线程之线程池的更多相关文章

  1. java 22 - 20 多线程之线程池

    程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互. 而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池. 线程池里的每一个线程代码结束后 ...

  2. Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  3. java基础:简单实现线程池

    前段时间自己研究了下线程池的实现原理,通过一些源码对比,发现其实核心的东西不难,于是抽丝剥茧,决定自己实现一个简单线程池,当自已实现了出一个线程池后.发现原来那么高大上的东西也可以这么简单. 先上原理 ...

  4. Java基础学习——多线程之创建任务

    这次来盘点一下Java中用线程执行任务的写法. 1.扩展Thread 最基本的实现方法是在创建一个继承Thread的新类,在其中覆盖run()方法执行任务. public class MyThread ...

  5. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

  6. Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析

    目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...

  7. Java多线程与线程池技术

    一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...

  8. Java 多线程:线程池

    Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...

  9. JAVA多线程(三) 线程池和锁的深度化

    github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...

随机推荐

  1. golang的json序列化

    json就是简单的数据交换格式,语法类似javascript的对象和列表,是最常见的后端和运行在网页上的js之间的通信格式. encoding: 编码json数据需要使用到Marshal()函数. f ...

  2. python装饰器三种装饰模式的简单理解

    学设计模式中有个装饰模式,用java实现起来不是很难,但是远远没有python简单,难怪越来越火了! 这里就简单讨论下python的几种装饰模式: 一 无参装饰器: # 装饰器 import time ...

  3. 【codeforces】【比赛题解】#854 CF Round #433 (Div.2)

    cf一如既往挺丧 看丧题点我! [A]分数 Petya是数学迷,特别是有关于分数的数学.最近他学了所谓一个分数被叫做“真分数”当且仅当其分子小于分母,而一个分数被叫做“最简分数”当且仅当其分子分母互质 ...

  4. Linux USB驱动框架分析 【转】

    转自:http://blog.chinaunix.net/uid-11848011-id-96188.html 初次接触与OS相关的设备驱动编写,感觉还挺有意思的,为了不至于忘掉看过的东西,笔记跟总结 ...

  5. MySQL参数设置

    InnoDB配置 从MySQL 5.5版本开始,InnoDB就是默认的存储引擎并且它比任何其它存储引擎的使用要多得多.那也是为什么它需要小心配置的原因. 1 innodb_file_per_table ...

  6. 事件,使用.net自带委托EventHandler

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. Python操作Excle

    python操作excel主要用到xlrd和xlwt这两个库,即xlrd是读excel,xlwt是写excel的库.可从这里下载https://pypi.python.org/pypi.下面分别记录p ...

  8. 使用os模块实现展示目录下的文件和文件夹

    Windows 10家庭中文版,Python 3.6.4 今天学习了os模块,下面是使用它开发的一个展示目录下的文件和文件夹的函数,代码如下: import os # deep大于等于1的整数,默认为 ...

  9. 再谈OPENCV(转)

    转自:http://blog.csdn.net/carson2005/article/details/6979806 尽管之前写过一篇关于OpenCV的介绍(http://blog.csdn.net/ ...

  10. 关于json中转义字符/正斜杠的问题。

    1.首先有关转义字符 可以看百度百科: 先不管/是否需要转义,我们去json的官方网站去看看:http://www.json.org/ 可见有这个,那么意思是 json中 又规定建议了一下,意思是虽然 ...