博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Executor 框架
阅读量:4980 次
发布时间:2019-06-12

本文共 4424 字,大约阅读时间需要 14 分钟。

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 
Future
submit(Callable
task)public
Future
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
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
task) Future
f3 = executor.submit(new Callable
() { @Override public String call() throws Exception { System.out.println(3); return "result"; } }); System.out.println(f3.get()); executor.shutdown(); }}

执行结果

1result2null3result

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

public static Callable callable(Runnable task)public static Callable
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());

执行结果

4null5result2

转载于:https://www.cnblogs.com/yuanmiemie/p/8566066.html

你可能感兴趣的文章
如何确定VS编译器版本
查看>>
设置PL/SQL 快捷键
查看>>
个人阅读作业7
查看>>
转载:深入浅出Zookeeper
查看>>
GMA Round 1 新程序
查看>>
node anyproxy ssi简易支持
查看>>
PHP函数 ------ ctype_alnum
查看>>
HDU 1102 Constructing Roads
查看>>
多线程之ThreadLocal类
查看>>
OC语言description方法和sel
查看>>
C#中得到程序当前工作目录和执行目录的五种方法
查看>>
python 迭代器与生成器
查看>>
[django]form的content-type(mime)
查看>>
仿面包旅行个人中心下拉顶部背景放大高斯模糊效果
查看>>
C# 小叙 Encoding (二)
查看>>
CSS自学笔记(14):CSS3动画效果
查看>>
项目应用1
查看>>
基本SCTP套接字编程常用函数
查看>>
C 编译程序步骤
查看>>
[Git] 005 初识 Git 与 GitHub 之分支
查看>>