1. 先来看一下类构成

public interface Executor {   //顶级接口Executor,定义了线程执行的方法

    void execute(Runnable command);
}
public interface ExecutorService extends Executor {

  //定义了线程池周期相关的方法
void shutdown(); //平缓的关闭:不再接受新的任务,同时等待已经提交的任务的完成(包括还未开始执行的任务) List<Runnable> shutdownNow();  //粗暴的关闭,尝试取消正在执行的任务,同时不再继续执行提交但未开始的任务 boolean isShutdown(); //查看该执行器是否关闭 boolean isTerminated();    //查询线程池是否终止 boolean awaitTermination(long timeout, TimeUnit unit) //等待线程池达到终止状态,通常在此方法后调用shutdown()达到同步关闭线程池的效果
throws InterruptedException; <T> Future<T> submit(Callable<T> task); //submit()方法用来提交带有返回值的任务 <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) //用来提交复数的任务
throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}

2. ThreadPoolExecutor为线程池的实现

public ThreadPoolExecutor(int corePoolSize,       //核心线程数量,代表在空闲状态下线程池中维持的线程的数量
int maximumPoolSize, //线程池所能允许的最大线程数量
long keepAliveTime,  //空闲线程的存活时间
TimeUnit unit,    //时间单位
BlockingQueue<Runnable> workQueue, //用来暂时保存任务的队列
ThreadFactory threadFactory,      //用来创建线程
RejectedExecutionHandler handler) {   //拒绝策略,在任务无法加入到队列是发挥作用 }

3. 拒绝策略

  (1)AbortPolicy: 该策略抛出RejectedExecutionException,调用者捕获异常后进行处理。

  (2)DiscartPolicy:当新任务无法加入到队列中是,该策略悄悄抛弃该任务。

  (3)DiscardOldestPolicy:该策略将抛弃即将要执行的任务。

  (4)CallerRunsPolicy:该策略将某些任务回退到调用者。

4. 四种类型的线程池(通用线程池的方法定义在Executors类中)

  当线程池的所有参数有效设置时提交任务的完整过程:查看当前线程数量是否大于corePoolSize,若小于则创建一个新的线程来执行该任务,否则将该任务加入到workQueue中;若workerQueue也满,那么查看线程的数量是否小于maximumPoolSize,若小于则创建新的线程来执行,否则执行抛弃策略。另外若线程空闲时间大于keepAliveTime,则销毁线程。

 public ThreadPoolExecutor(int corePoolSize,            //通用构造方法
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler); //使用默认的线程工厂和默认的拒绝策略
}
private static final RejectedExecutionHandler defaultHandler =        //默认为AbortPolicy
new AbortPolicy();
 

  (1)newFixedThreadPool :创建一个固定大小的线程池

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, //核心数量=最大数量,keepAliveTime=0(若无以外线程将一直存在),workQueue使用LinkedBlockingQueue
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {   //另一个构造方法,可指定线程工厂
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
 
 

  (2)newCachedThreadPool:创建一个可更具需要的线程池

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, //核心大小=0,最大数量不限,存活时间为60s(若长时间没有任务则该线程池为空),使用SynchronousQueue作为workeQueue
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

  (3)newScheduledThreadPool:创建一个可延迟执行任务的线程池

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
 public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, //指定核心大小,不限最大数量,线程不会过期,使用DelayedWordeQueue作为workeQueue
new DelayedWorkQueue());
}

  (4)newSingleThreadPool:创建一个只有一个线程的线程池

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1, //核心数量与最大数量都为1,存活时间不限,使用LinkedBlockingQueue作为workQueue
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

java线程池的介绍与使用(Executor框架)的更多相关文章

  1. Java 线程池的介绍以及工作原理

    在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗.2. 提高响应速度: ...

  2. Java 线程池详细介绍

    根据摩尔定律(Moore’s law),集成电路晶体管的数量差不多每两年就会翻一倍.但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长.处理器制造商花了很多年来提高时钟频率和指令并行.在 ...

  3. Java线程池管理及分布式Hadoop调度框架搭建

    平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发工程师却在这个上面吃了不少苦头. 怎么做一套简便的线程开发模 ...

  4. Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析

    目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolEx ...

  5. 深入理解Java线程池:ThreadPoolExecutor

    线程池介绍 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题: 如果并发的请求数量非常多,但每个线 ...

  6. Java线程池使用和源码分析

    1.为什么使用线程池 在多线程编程中一项很重要的功能就是执行任务,而执行任务的方式有很多种,为什么一定需要使用线程池呢?下面我们使用Socket编程处理请求的功能,分别对每种执行任务的方式进行分析. ...

  7. Java线程池学习总结

    一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率. 线程池提供了 ...

  8. (转载)JAVA线程池管理

    平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...

  9. Java线程池的那些事

    熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...

随机推荐

  1. 讲真,MySQL索引优化看这篇文章就够了

    本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开. 一.MySQL——索引基础 首先,我们将从索引基础开始介绍一下什么 ...

  2. SQL注入靶场sqli-labs 1-65关全部通关教程

    以前说好复习一遍 结果复习到10关就没继续了 真是废物 一点简单的事做不好 继续把以前有头没尾的事做完 以下为Sqli-lab的靶场全部通关答案 目录: less1-less10 less10-les ...

  3. Ubuntu 19.10 发布 | 云原生生态周报 Vol. 24

    作者 | 木苏.进超.冬岛.元毅.心水.衷源 业界要闻 1.云原生编程语言 Pulumi 1.0 pulumi ,一款中立的开源云开发平台,Pulumi 支持多语言.混合云环境.完全可扩展.初期支持 ...

  4. NodeJs编写Cli实现自动初始化新项目目录结构

    应用场景 前端日常开发中,会遇见各种各样的cli,这些工具极大地方便了我们的日常工作,让计算机自己去干繁琐的工作,而我们,就可以节省出大量的时间用于学习.交流.开发. 注释:文章附有源码链接! 使用工 ...

  5. RIDE的Edit界面

    有四种类型的Edit界面(注:测试套件主要是存放测试案例,资源文件主要是存放用户关键字) 1.测试套件(file类型)的Edit界面 首先展开Setting: 对右侧红框按钮简单说明: Library ...

  6. Django之视图层的简介与使用

    Django的View(视图) 一个视图函数(可以是类),简称视图,是一个简单的Python 函数(可以是类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个 ...

  7. 整理了适合新手的20个Python练手小程序

    100个Python练手小程序,学习python的很好的资料,覆盖了python中的每一部分,可以边学习边练习,更容易掌握python. 本文附带基础视频教程:私信回复[基础]就可以获取的 [程序1] ...

  8. day03课堂练习

    简述变量的组成 变量由变量名,赋值符号,和变量值三个部分组成 简述变量名的命名规范 a.变量名必须有意义,要能反映变量值所描述的状态 b.变量名以字母.数字和下划线组成,不能用数字开头 c.不能以关键 ...

  9. Linux 编译与交叉编译

    在Linux环境中,所处平台不同,执行文件也就不同,同一执行文件不能在不同平台下使用 如在Ubnutu下 是用gcc编译一个.c文件 gcc main.c -o main.out -o 可以指定输出文 ...

  10. Python3爬虫(3)_urllib.error

    注:参照https://blog.csdn.net/c406495762/article/details/59488464 Learn_ERROR: urllib.error可以接收有urllib.r ...