Java的线程既是工作单元,也是执行机制。从JDK5开始,把工作单元与执行机制分离开来。工作单元包括RunnableCallable,而执行机制由Executor框架提供。

Executor 框架简介

HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当该Java线程终止时,这个操作系统线程也被收回。操作系统会调度所有线程并将他们分配给可用的CPU。如图

Executor 框架结构

主要由3大部分组成:

  • 任务:包括被执行任务需要实现的接口:Runnable接口和Callable接口
  • 任务的执行:包括任务执行机制的核心接口Executor,以及继承自它的ExecutorService接口。有两个关键类实现了ExecutorService接口(ThreadPoolExecutorScheduledThreadPoolExecutor)。
  • 异步计算的结果:包括接口Future和实现它的FutureTask
Executor框架的成员
  • ThreadPoolExecutor:通常使用工具类Executors来创建。Executors可以创建3种类型的ThreadPoolExecutor:

    • SingleThreadExecutor:用于需要保证顺序地执行每个任务,并且在任意时间点不会有多个线程是活动的应用场景。下面是创建单个线程的API
    public static ExecutorService newSingleThreadExecutor();
    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory)
    • FixedThreadPool:用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,它适用于负载比较重的服务器。下面是创建使用固定线程数的FixedThreadPool的API
    public static ExecutorService newFixedThreadPool(int nThreads);
    public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
    • CachedThreadPool:它是无界大小的线程池,用于执行很多短期异步小任务的小程序,或者是负载比较轻的服务器。下面是创建一个根据需要创建新线程的API
    public static ExecutorService newCachedThreadPool();
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
  • ScheduledThreadPoolExecutor:通常使用工具类Executors来创建。Executors可以创建2种类型的ScheduledThreadPoolExecutor:
    • ScheduledThreadPoolExecutor:包含若干个线程的ScheduledThreadPoolExecutor,适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而需要限制后台线程的数量的场景。下面是创建的API:
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
    public static ScheduledExecutorService newScheduledThreadPool(
    int corePoolSize, ThreadFactory threadFactory);
    • SingleThreadScheduledExecutor:只包含一个线程的ScheduledThreadPoolExecutor,适用于需要单个线程执行周期任务,同时需要保证顺序地执行各个任务的场景。下面是创建的API:
    public static ScheduledExecutorService newSingleThreadScheduledExecutor();
    public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory);
  • Future接口

    Future接口和实现Future接口的FutureTask类用来表示异步计算的结果。当我们把Runnable接口或Callable接口的实现类提交(submit)给ThreadPoolExecutorScheduledThreadPoolExecutor时,ThreadPoolExecutorScheduledThreadPoolExecutor会向我们返回一个FutureTask对象。下面是对应API:
public <T> Future<T> submit(Callable<T> task)
public <T> Future<T> submit(Runnable task, T result)
public Future<?> submit(Runnable task)
  • Runnable接口和Callable接口

    这两个接口的实现类都可以被ThreadPoolExecutorScheduledThreadPoolExecutor执行,最后一个方法没有返回值,其他均可以通过得到的FutureTask对象的get方法获取执行后结果。
public class ExecutorTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(5);
//submit(Runnable task)
Future<String> f1 = executor.submit(new Runnable(){
@Override
public void run() {
System.out.println(1);
}
},"result");
System.out.println(f1.get());
//submit(Runnable task,T result)
Future f2 = executor.submit(new Runnable(){
@Override
public void run() {
System.out.println(2);
}
});
System.out.println(f2.get());
//submit(Callable<T> task)
Future<String> f3 = executor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println(3);
return "result";
}
});
System.out.println(f3.get()); executor.shutdown();
}
}

执行结果

1
result
2
null
3
result

除了自己实现Callable接口外,Executors可以把一个Runnable包装成一个Callable,下面是对应的API

public static Callable<Object> callable(Runnable task)
public static Callable<T> callable(Runnable task, T result)

此时将这种转换过的对象交给ThreadPoolExecutorScheduledThreadPoolExecutor执行时,第一个种转换方法不会有返回值。

        Callable c1 = Executors.callable(new Runnable() {
@Override
public void run() {
System.out.println(4);
}
}); Callable c2 = Executors.callable(new Runnable() {
@Override
public void run() {
System.out.println(5);
}
},"result2"); Future f4 = executor.submit(c1);
System.out.println(f4.get());
Future f5 = executor.submit(c2);
System.out.println(f5.get());

执行结果

4
null
5
result2

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. springboot集成mybatis及mybatis generator工具使用

    原文链接 前言mybatis是一个半自动化的orm框架,所谓半自动化就是mybaitis只支持数据库查出的数据映射到pojo类上,而实体到数据库的映射需要自己编写sql语句实现,相较于hibernat ...

  2. rsync+inotify文件同步 - 同步慢的问题

    rsync+inotify文件同步 - 同步慢的问题 我们来看网上的教程,我加了注释.(网上所有的教程基本都一模一样,尽管写法不一样,致命点都是一样的) #!/bin/bash /usr/bin/in ...

  3. Go开发环境安装配置

    访问下载地址:https://golang.org/dl/ 32位系统下载go1.8.1.linux-386.tar.gz,64位系统下载go1.8.1.linux-amd64.tar.gz, 假定你 ...

  4. inputsimulator - Windows Input Simulator

    窗体输入模拟器提供一个基于 win32 SendInput  方法的 模拟键盘鼠标输入的.net 接口.windows 输入模拟器可用于 WPF.windows 窗体和控制台应用程序, 实现模拟任意按 ...

  5. SQL 基础学习(2) Joining 和function , 作业没有做,需要看百宝箱。NOsql的概念

    SQL 基础学习(2) Joining 可以同时关联(joining)多张表进行复杂的查询. 相比于用Rails捞出数据再用Ruby进行过滤组合,使用SQL更加高效,节能. 以下是 users has ...

  6. codeforces 555a//Case of Matryoshkas// Codeforces Round #310(Div. 1)

    题意:1-n的数字,大的在小的后面,以这种规则已经形成的几个串,现在要转为一个串,可用的操作是在末尾拆或添加,问要操作几次? 模拟了很久还是失败,看题解才知道是数学.看来这种只要结果的题,模拟很不合算 ...

  7. Oracle ASM 相关的 视图(V$) 和 数据字典(X$)

    本文转自: http://blog.csdn.net/tianlesoftware/article/details/6733039 ASM由于其高度的封装性,使得我们很难知道窥探其内部的原理.可以通过 ...

  8. The Architecture of Open Source Applications——阅读笔记part 1

    Architects look at thousands of buildings during their training, and study critiques of those buildi ...

  9. C++实现Vector容器的基本功能

    本文只实现了Vector的默认构造函数.赋值构造函数.赋值函数.析构函数.重置空间大小函数和插入函数,权当起到抛砖引玉的作用,其他函数功能的实现可在此基础之上进行拓展. #include <io ...

  10. POJ 2896 AC自动机 or 暴力

    DESCRIPTION :大意是说.给你n个代表病毒的字符串.m个表示网站的字符串.让你计算有多少个网站被病毒感染了.被那些病毒感染了. 刚开始就想暴力.然而,忽略了条件:每个网站最多有三个病毒.于是 ...