摘要:

       Executor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务的线程相当于消费者,并用Runnable来表示任务,Executor的实现还提供了对生命周期的支持,以及统计信息收集,应用程序管理机制和性能监视等机制。
 
一、Exexctor简介

 Executor的UML图:(常用的几个接口和子类)
                          

Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command),

 
ExecutorService:是一个比Executor使用更广泛的子类接口,其提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行状况返回Future的方法
 
AbstractExecutorService:ExecutorService执行方法的默认实现
 
ScheduledExecutorService:一个可定时调度任务的接口
 
ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池
 
ThreadPoolExecutor:线程池,可以通过调用Executors以下静态工厂方法来创建线程池并返回一个ExecutorService对象:
 

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

  在HotSpot VM的线程模型中,JAVA线程被一对一映射为本地操作系统线程。JAVA线程启动时会启动一个本地操作系统线程:当该JAVA线程终止时,这个操作系统线程也会被回收。操作系统会调度所有线程并将它们分配给可用的CPU。
 
 两级调度模型的示意图:
                  

 从图中可以看出,该框架用来控制应用程序的上层调度(下层调度由操作系统内核控制,不受应用程序的控制)。

 

三、Executor框架的结构

 Executor主要由三部分组成:任务产生部分,任务处理部分,结果获取部分。(设计模式:生产者与消费者模式)

先来看个图:

                  

1.任务的产生:Runnable接口和Callable接口

  这2个对象属于任务对象。工具类Executors可以把一个Runnable对象封装为Callable对象。当我们拥有任务对象之后,就可以将其交给ExecutorService(Executor的一个实现接口)了,这样转入第二部分–任务处理部分。
 

2.任务的处理:Executor接口—>ExecutorService接口 

  任务的处理主要是将任务丢到线程池中,由线程池提供线程将任务“消费掉”。

  线程池有2类:ThreadPoolExecutor和ScheduledThreadPoolExecutor。2种线程池类均可以通过工厂类Executors来创建。  

 ⑴:ThreadPoolExecutor类

  工厂类可以创建3种类型的ThreadPoolExecutor类:

    ①:FixedThreadPool:拥有固定数量线程的线程池,限制了线程的数目,适用于负载比较重的服务器。

    ②:SingleThreadPool:单个线程的线程池,适用于需要保证顺序的执行各个任务;任意时间点,不会有多个线程活动。

    ③:CachedThreadPool:大小无界的线程池,适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器。

 ⑵:ScheduleThreadPoolExecutor类
  工厂类可以创建2种类型的SchedulePoolExecutor类:

    ①:ScheduleThreadPoolExecutor:包含若干线程。

    ②:SingleThreadScheduleExecutor:单个线程。

3.任务结果的获取:Future接口

  Future接口有个实现类FutureTask,迄今为止API中返回的都是FutureTask对象,未来的JDK实现中,可能有Future对象。
 

四、Executors类

 Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
                 

例子:newCachedThreadPool

/**
* 运行结果:可以看出缓存线程池大小是不定值,可以需要创建不同数量的线程,
* 在使用缓存型池时,先查看池中有没有以前创建的线程,如果有,就复用.如果没有,就新建新的线程加入池中,
* 缓存型池子通常用于执行一些生存期很短的异步型任务
*
*/
public class newCachedThreadPoolTest {
public static void main(String[] args) {
//创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程
ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 20; i++) {
Runnable syncRunnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
executorService.execute(syncRunnable);
}
}
}

console输出结果:

例子:newFixedThreadPool

/**
* 运行结果:总共只会创建5个线程, 开始执行五个线程,
* 当五个线程都处于活动状态,再次提交的任务都会加入队列等到其他线程运行结束,当线程处于空闲状态时会被下一个任务复用
*
*/
public class newFixedThreadPoolTest {
public static void main(String[] args) {
//Executors工厂类创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i = 0; i < 20; i++) {
Runnable synRunnable = new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
executorService.execute(synRunnable);
}
}
}

console输出结果:

例子:newScheduledThreadPool

public class newScheduledThreadPoolTest {
public static void main(String[] args) {
//创建一个定长线程池,支持定时及周期性任务执行
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
for (int i = 0; i < 20; i++) {
final int count = i;
Runnable syncRunnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " ----- " + count);
}
};
//表示从提交任务开始计时,5000毫秒后执行
//运行结果和newFixedThreadPool类似,不同的是newScheduledThreadPool是延时一定时间之后才执行
executorService.schedule(syncRunnable, 5000, TimeUnit.MILLISECONDS);
}
}
}

console输出结果:

例子:newSingleThreadExecutor

public class newSingleThreadExecutorTest {
public static void main(String[] args) {
//创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
//运行结果:只会创建一个线程,当上一个执行完之后才会执行第二个
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 20; i++) {
Runnable syncRunnable = new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
};
executorService.execute(syncRunnable);
}
}
}

console输出结果:

结合Future接口来做一个实测

public class FutureDemo {

    public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(3); // CompletionService接口内部维护一个结果队列:一堆future....
CompletionService<Integer> cs = new ExecutorCompletionService<>(pool); for (int i = 1; i < 11; i++) {
final int flag = i * 10;
cs.submit(new Callable<Integer>() { @Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
return flag;
}
});
} for (int i = 0; i < 11; i++) {
try {
System.out.println(cs.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} pool.shutdown();
}
}

console输出结果:

附录一张图来介绍Executor框架

资料出处:https://blog.csdn.net/qq_16811963/article/details/52161713

     https://blog.csdn.net/qq_35794278/article/details/81481483

 
 

Executor框架(转)的更多相关文章

  1. java并发编程(十七)Executor框架和线程池

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497   Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...

  2. Executor框架(转载)

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...

  3. Java并发和多线程(二)Executor框架

    Executor框架 1.Task?Thread? 很多人在学习多线程这部分知识的时候,容易搞混两个概念:任务(task)和线程(thread). 并发编程可以使我们的程序可以划分为多个分离的.独立运 ...

  4. java并发编程-Executor框架

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...

  5. 戏(细)说Executor框架线程池任务执行全过程(上)

    一.前言 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不 ...

  6. 戏(细)说Executor框架线程池任务执行全过程(下)

    上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现Th ...

  7. Java并发——线程池Executor框架

    线程池 无限制的创建线程 若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时: 线程生命周期的开销非常高 资源消耗 稳定性 引入线程池 任务是一组逻辑 ...

  8. Java Executor 框架学习总结

    大多数并发都是通过任务执行的方式来实现的.一般有两种方式执行任务:串行和并行. class SingleThreadWebServer { public static void main(String ...

  9. Executor框架

     Executor框架是指java5中引入的一系列并发库中与executor相关的功能类,包括Executor.Executors.ExecutorService.CompletionService. ...

  10. Java Executor 框架

    Java Executor 框架 Executor框架是指java5中引入的一系列并发库中与executor相关的功能类,包括Executor.Executors. ExecutorService.C ...

随机推荐

  1. 学习sklearn聚类使用

    学习利用sklearn的几个聚类方法: 一.几种聚类方法 1.高斯混合聚类(mixture of gaussians) 2.k均值聚类(kmeans) 3.密度聚类,均值漂移(mean shift) ...

  2. echarts 有关饼形图和map的使用技巧1(饼图)

    http://blog.csdn.net/yhn1121/article/details/52041742 先上个链接,百度无意间搜到的,写得比我全面,可以直接飞去看它: 之前写网页用过echarts ...

  3. python中super().__init__和类名.__init__的区别

    super().__init__相对于类名.__init__,在单继承上用法基本无差 但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次 多继承时 ...

  4. Java常考面试题整理(五)

    81.RMI中的远程接口(Remote Interface)扮演了什么样的角色? 参考答案: 远程接口用来标识哪些方法是可以被非本地虚拟机调用的接口.远程对象必须要直接或者是间接实现远程接口.实现了远 ...

  5. 上传本地文件到linux

    Linux 命令行上传文件 Linux服务器,硬盘坏了,更换硬盘后,重装了好像是Foreda v22的操作系统,我在/var/www/html/目录下新建了我的个人文件夹 kma,然后我在此kma文件 ...

  6. ycache分布式缓存框架

    介绍   ycache是yhd的分布是缓存框架,设计目的是提供易扩展.高可靠的分布式缓存系统.ycache从全局视角分配和管理缓存,检测缓存的状态并做故障恢复.   当应用(应用:使用ycache的上 ...

  7. PHP CI框架数据库常用操作

    例子 <?php defined('BASEPATH') OR exit('No direct script access allowed'); class Menu extends CI_Co ...

  8. QBXT七月D1

    今天是lyd神仙讲课的第一天,可以感觉到的是这位神仙有着不同于他人的气质,比如他的表情包(雾) 好了来讲正经的) 今天讲的比较多的是模拟算法和一些比赛中的好习惯 high-level 这个名词的大体意 ...

  9. 对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们

    托管调试助手“CallbackOnCollectedDelegate”在“D:\XXX\XXX.vshost.exe”中检测到问题. 其他信息: 对“XXX+HookProc::Invoke”类型的已 ...

  10. foundation DB问题

    1. go get github.com/apple/foundationdb/bindings/go/src/fdb # github.com/apple/foundationdb/bindings ...