一、Executor概述

为更好控制线程,jdk提供一套线程管理框架Executor,帮助开发人员有效地进行线程控制。它们都位于java.util.concurrent包中,是jdk并发包的核心。其中有个比较重要的类:Executors,他扮演着线程工厂的角色,我们可以通过Executors创建特定功能的线程池。

二、Executors创建线程的方法

newFixedThreadPool()方法:返回一个固定数量的线程池,线程数始终不变,当有一个任务提交时,若线程池中空闲,则立即执行;若没有,则会被暂缓在一个任务队列里等待有空闲的线程去执行(队列是无界队列,无限缓存线程数)

newSingleThreadPoolExecutor()方法:创建一个线程的线程池,若空闲则执行,若没空闲线程则暂缓在任务队列(队列是无界队列,无限缓存线程数)

newCachedThreadPool():返回一个可根据实际情况调整线程个数的线程池,不限制最大线程数量,若有任务则创建线程执行,若无任务则不创建线程,并且每个空线程会在60s后自动回收。(初始化不创建线程)

newScheduledThreadPool():返回一个ScheduledExecutorService对象,但该线程池可以指定线程的数量(不限线程池数量),带有延迟时间的去获取线程。通常用spring的Scheduled

这4个方法返回的都是ThreadPoolExecutor对象

三、自定义线程池——ThreadPoolExecutor

若Executors的工厂方法无法满足我们的需求,可以自己用ThreadPoolExecutor去创建自定义的线程池(其实Executors的工厂方法内部就是用ThreadPoolExecutor类实现的)

(1)构造方法如下

public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler)

corePoolSize:核心线程数

maximumPoolSize:最大线程数

keepAliveTime:每个线程保持活着的空闲时间数字

unit:keepAliveTime的时间单位

workQueue:存放线程的队列(线程超过maximumPoolSize时用到)

threadFactory:线程工厂,主要用来创建线程

handler:拒绝任务执行的处理器(情景:假设线程池数量最大为3,队列长度最大为2,现在有3个任务在执行未释放线程,而任务里也有2个任务在排队了,我们认为后面再来任务就可以丢弃了,这个handler处理的就是这种情况)

有以下四种取值:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。(JDK默认的拒绝策略)

ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

ThreadPoolExecutor.CallerRunsPolicy:只要线程池不关闭,该策略直接在调用者线程中,运行当前被丢弃的任务

个人认为这4中策略不友好,最好自己定义拒绝策略,实现RejectedExecutionHandler接口

构造方法详细解读:

a.构造方法的队列类型比较关键

如果使用有界队列

1).初始的poolSize < corePoolSize,提交的runnable任务,会直接做为new一个Thread的参数,立马执行 。

2).当提交的任务数超过了corePoolSize,会将当前的runable提交到一个block queue中。

3).有界队列满了之后,如果poolSize < maximumPoolsize(poolSize是在运行的线程数,不包括队列里面的线程)时,会尝试new 一个Thread的进行救急处理,立马执行对应的runnable任务。

4).如果3中也无法处理了(poolSize > maximumPoolsize),就会走到第四步执行reject操作。

如果使用无界队列,与有界队列相比,除非系统资源耗尽,否则无界的任务队列不存在任务入队失败的情况。当有新的任务到来,系统的线程数小于corePoolSize时,则新建线程执行任务。当达到corePoolSize后,就不会继续增加,若后续仍有新的任务加入,而没有空闲的线程资源,则任务直接进入队列等待。若任务创建和处理的速度差异很大,无界队列会保持快速增长,直到耗尽系统内存。(此时maximumPoolSize无意义)

四、ThreadPoolExecutor的submit与excute的区别

1.submit可以传入Callable接口的实例对象

2.submit方法有返回值

JAVA Executor(线程池)框架的更多相关文章

  1. Java并发—线程池框架Executor总结(转载)

    为什么引入Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞 ...

  2. Executor线程池框架

    Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致 ...

  3. 基础线程机制--Executor线程池框架

    基础线程机制 Executor线程池框架 1.引入Executor的原因 (1)new Thread()的缺点 ​  每次new Thread()耗费性能 ​  调用new Thread()创建的线程 ...

  4. Java并发编程(08):Executor线程池框架

    本文源码:GitHub·点这里 || GitEE·点这里 一.Executor框架简介 1.基础简介 Executor系统中,将线程任务提交和任务执行进行了解耦的设计,Executor有各种功能强大的 ...

  5. Java Executor 线程池

  6. Java多线程系列 JUC线程池01 线程池框架

    转载  http://www.cnblogs.com/skywang12345/p/3509903.html 为什么引入Executor线程池框架 new Thread()的缺点 1. 每次new T ...

  7. Java中线程池的实现原理

    知识点总结 ---------------------------------------------------------------------------------------------- ...

  8. Java中线程池的实现原理-求职必备

    jdk1.5引入Executor线程池框架,通过它把任务的提交和执行进行解耦,只需要定义好任务,然后提交给线程池,而不用关心该任务是如何执行.被哪个线程执行,以及什么时候执行. 初始化线程池(4种) ...

  9. Executor线程池

    Executor线程池框架: 使用线程池的优点: 1.重用存在的线程 2.减少对象创建.消亡的开销 3.性能佳 4.可有效控制最大并发线程数,提高系统资源的使用率 5.避免过多资源竞争,避免堵塞 6. ...

  10. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

随机推荐

  1. 速刷git<一> 常用命令记录

    git config  --list 列出配置  --local 对某个仓库有效  --global 对当前用户的所有仓库有效  --system 对系统所有登录用户有效git reset  --ha ...

  2. moviepy音视频剪辑:与time时间线相关的变换函数freeze_region、make_loopable、speedx、time_mirror、time_symmetrize介绍

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>介绍了剪辑基类的fl.fl_time.fx方法,在<movi ...

  3. Python中对输入的可迭代对象元素排序的sorted函数

    sorted根据输入可迭代对象中的项返回一个新的已排序列表,原输入参数对象中的数据不会发生变化. 具体可参考:<Python中与迭代相关的函数>的详细介绍 老猿Python,跟老猿学Pyt ...

  4. PyQt(Python+Qt)学习随笔:containers容器类部件QStackedWidget重要方法介绍

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 StackedWidget堆叠窗口部件为一系列窗口部件的堆叠,对应类为QStackedWidget. ...

  5. java后端开发学习路线

    思维导图(欢迎克隆):https://www.processon.com/mindmap/5f563cd31e08531762c4e32b 主要包括:编程基础.研发工具.应用框架.运维知识(主要学会配 ...

  6. IDM 6.37.8 绿色特别版 (4月4日更新)

    Internet Download Manager,全球最流行的下载工具.Internet Download Manager (简称IDM) Windows 平台功能强大的多线程下载工具,国外非常受欢 ...

  7. javascript编写原则

    1.不要在同一行声明多个变量2.使用===或!==来比较3.使用字面量的方式来创建对象.数组,替代new Array这种形式4.switch语句必须要带default分支5.fon-in循环中的变量, ...

  8. 认识 Cargo-Rust构建工具和包管理器

    认识 Cargo-Rust构建工具和包管理器 上两篇文章 都有说到 hello world 程序,但是我们如果使用自己创建文件的方式创建项目,一旦文件多了,那得多麻烦,整个项目将变得难以管理.下面我来 ...

  9. Codeforces Edu Round 65 A-E

    A. Telephone Number 跟之前有一道必胜策略是一样的,\(n - 10\)位之前的数存在\(8\)即可. #include <iostream> #include < ...

  10. Ubuntu18开机执行shell命令

    1.打开shell终端,输入 sudo vi /etc/rc.local 2.在编辑器里面输入自己要启动的脚本,特别强调:脚本(程序)要有可执行权限 #!/bin/bash echo "ru ...