Executor框架详解

java的线程既是工作单元,也是执行机制。从jdk5开始,把工作单元与执行机制分离开来。工作单元包括Runnable和Callable,而执行机制由Executor框架提供。这样一来Executor是基于生产者消费者模式的,提交任务的操作相当于生成者,执行任务的线程相 当于消费者。

一、Executor框架的两级调度模型

在HotSpot VM的模型中,JAVA线程被一对一映射为本地操作系统线程。JAVA线程启动时会创建一个本 地操作系统线程,当JAVA线程终止时,对应的操作系统线程也被销毁回收,而操作系统会调度所有线程 并将它们分配给可用的CPU。

在上层,JAVA程序会将应用分解为多个任务,然后使用应用级的调度器(Executor)将这些任务映射成 固定数量的线程;在底层,操作系统内核将这些线程映射到硬件处理器上。





1、从类图上看,Executor接口是异步任务执行框架的基础,该框架能够支持多种不同类型的任务执行策略。Executor接口就提供了一个执行方法,任务是Runnbale类型,不支持Callable类型。

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

2、ExecutorService接口实现了Executor接口,主要提供了关闭线程池和submit方法:

public interface ExecutorService extends Executor {
List<Runnable> shutdownNow();
boolean isTerminated();
<T> Future<T> submit(Callable<T> task);
}

另外该接口有两个重要的实现类:ThreadPoolExecutor与ScheduledThreadPoolExecutor。其中ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务;而 ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行任务,或者定期执行命令。

在上一篇文章中,我是使用ThreadPoolExecutor来通过给定不同的参数从而创建自己所需的线程池,但是在后面的工作中不建议这种方式,推荐使用Exectuors工厂方法来创建线程池

Executor框架使用示意图



1、主线程首先要创建实现Runnable或者Callable接口的任务对象工具类Executors,可以把一个Runnable对象封装为一个Callable对象(Executors.callable(Runnable task) 或者 Executors.callable(Runnable task,Object resule))。

2、然后可以把Runnable对象直接交给ExecutorService执行(ExecutorService.execute(Runnable command));或者可以把Runnable对象或Callable对象提交给ExecutorService执行(ExecutorService.submit(Runnable task) 或 ExecutorService.submit(Callable task))。

3、如果执行ExecutorService.submit(…),ExecutorService将返回一个实现Future接口的对象(FutureTask)。由于FutureTask实现了Runnable,程序员也可以创建FutureTask,然后直接交给ExecutorService执行。

4、最后,主线程可以执行FutureTask.get()方法来等待任务执行完成。主线程也可以执行FutureTask.cancel(boolean mayInterruptIfRunning)来取消此任务的执行。

Executor框架的实现ThreadPoolExecutor

Executors可以创建3种类型的ThreadPoolExecutor:SingleThreadExecutorFixedThreadExecutorCachedThreadPool

1、SingleThreadExecutor:单线程线程池

ExecutorService threadPool = Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

我们从源码来看可以知道,单线程线程池的创建也是通过ThreadPoolExecutor,里面的核心线程数和线 程数都是1,并且工作队列使用的是无界队列。由于是单线程工作,每次只能处理一个任务,所以后面所 有的任务都被阻塞在工作队列中,只能一个个任务执行。

2、FixedThreadExecutor:固定大小线程池

ExecutorService threadPool = Executors.newFixedThreadPool(5);

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

这个与单线程类似,只是创建了固定大小的线程数量。

3、CachedThreadPool:无界线程池

ExecutorService threadPool = Executors.newCachedThreadPool();

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

无界线程池意味着没有工作队列,任务进来就执行,线程数量不够就创建,与前面两个的区别是:空闲 的线程会被回收掉,空闲的时间是60s。这个适用于执行很多短期异步的小程序或者负载较轻的服务 器。

Executor框架详解的更多相关文章

  1. 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术

    这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...

  2. java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService

    这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...

  3. Executor 框架详解

    框架最核心的类是ThreadPoolExecutor,它是Java线程池的实现类,通过Executors工具类,可以创建3种类型的ThreadPoolExecutor: 首先附上ThreadPoolE ...

  4. mina框架详解

     转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...

  5. Spark2.1.0——内置Web框架详解

    Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...

  6. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

  7. lombok+slf4j+logback SLF4J和Logback日志框架详解

    maven 包依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lomb ...

  8. [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解

    Core data 是 Cocoa 中处理数据,绑定数据的关键特性,其重要性不言而喻,但也比较复杂.Core Data 相关的类比较多,初学者往往不太容易弄懂.计划用三个教程来讲解这一部分: 框架详解 ...

  9. iOS 开发之照片框架详解(2)

    一. 概况 本文接着 iOS 开发之照片框架详解,侧重介绍在前文中简单介绍过的 PhotoKit 及其与 ALAssetLibrary 的差异,以及如何基于 PhotoKit 与 AlAssetLib ...

  10. Quartz.NET作业调度框架详解

    Quartz.NET作业调度框架详解 http://www.cnblogs.com/lmule/archive/2010/08/28/1811042.html

随机推荐

  1. Linux装cudnn

    https://stackoverflow.com/questions/66977227/could-not-load-dynamic-library-libcudnn-so-8-when-runni ...

  2. svn 中如何checkout出单个文件

    A 通过命令行操作 1.检出目录images svn co --depth=empty http://www.iusesvn.com/project1/images images_work_dir 这 ...

  3. js array map

      var user = ['Alice', 'Emily', 'Kate'];       console.log(user);      var keys = user.keys(); for ( ...

  4. tool script to convert back slash

    Back slash is used in windows, which makes so many headache for me. Then an idea came to my mind. It ...

  5. Vue 使用Lodop进行标签(条码)打印

    一.使用到的插件:vue-barcode(vue条形码插件),Lodop打印控件(我这里使用windows64版,所以以此进行举例说明.). 详述:前者(指vue-barcode)针对在前端界面上观察 ...

  6. EXPORT_SYMBOL的正常使用

    1.EXPORT_SYMBOL的作用是什么? EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以 ...

  7. nginx,git,maven面试题

    1.简述一下什么是Nginx,它有什么优势和功能? Nginx是一个web服务器和方向代理服务器,用于HTTP.HTTPS.SMTP.POP3和IMAP协议.因 它的稳定性.丰富的功能集.示例配置文件 ...

  8. 生成19位long型唯一数字id

    /** * 生成19位long型唯一数字id * @return */ public static long GetLong19UUID() { // String nanoRandom = Syst ...

  9. tensorboard 2.0可视化 —浏览器中输入http://ip:6006 - 无法访问此网站——有效解决

    https://blog.csdn.net/sinat_28442665/article/details/108975276

  10. 解决Ubuntu下的的“system program problem detected”问题

    解决Ubuntu下的的"system program problem detected"问题 1.删除crash文件 sudo rm /var/crash/*2.关闭pop up功 ...