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. [ios]ios画线 使用CGContextRef,CGPath和UIBezierPath来绘画

    参考 :http://www.mgenware.com/blog/?p=493 这三种东西:CGContextRef,CGPath和UIBezierPath.本质上都是一样的,都是使用Quartz来绘 ...

  2. 使用NativeExtension向AIR app 添加Activity和BroadCastReceiver(2)

    开发: Android项目 新建一个针对NativeExtension的Android项目,实现相应的FREContext,FREExtension和FREFunction等方法,同时新建一个Acti ...

  3. 【Robot Framework 项目实战 01】使用 RequestsLibrary 进行接口测试

    写在前面 本文我们一起来学习如何使用Robot Framework 的RequestsLibrary库,涉及POST.GET接口测试,RF用例分层封装设计等内容. 接口 接口测试是我们最常见的测试类型 ...

  4. C# int.ToString() 常用参数说明

    C#中int类型的ToString()方法有个重载是输入一个字符串,这个字符串可以对int进行部分格式化操作,如上.

  5. [.NET开发] C# BigInteger 处理超大整型数字

    今天遇到一个要处理XSD中Integer的数值区间的计算的问题,Integer这个类型的值区间理论上是可没有边界的,假设目前的值是1.5E+10000, 这个数字已经达到double和Int64都无法 ...

  6. GetTitleAndUrl

    Sub GetTitleAndUrl() Dim strText As String Dim i As Long Dim OneA Dim IsContent As Boolean Dim PageI ...

  7. 20170706wdVBA正则表达式提取题目

    Public Sub GetContents() Dim Reg As Object Dim Matches As Object Dim OneMatch As Object Dim Index As ...

  8. javaScript 的 map() reduce() foreach() filter()

    map(映射), reduce(规约), forEach(遍历), filter(过滤),它们都是高阶函数,都是以传入不同的函数来以不同的方式操作数组元.ie都不支持 一.map方法 *概述 map( ...

  9. Confluence 6 使用 LDAP 授权连接一个内部目录 - 服务器设置

    名字(Name) 名字的描述将会帮助你在目录中识别.例如: Internal directory with LDAP Authentication Corporate LDAP for Authent ...

  10. bzoj 1267 Kth Number I (点分治,堆)

    超级钢琴的树上版本, 类似做法即可, 只不过区间转为dfs序了, 用点分求一下, 复杂度$O(nlog^2n)$ #include <iostream> #include <algo ...