脚本宝典收集整理的这篇文章主要介绍了初读《Java并发编程的艺术》-第十章:Executor框架 -10.1 Executor框架简介,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
在java中,直接使用线程来异步的执行任务,线程的每次创建与销毁需要一定的计算机资源开销。每个任务创建一个线程的话,当任务数量多的时候,则对应的创建销毁开销会消耗大量的资源,这种策略最终可能会使处于高负荷状态的应用崩溃。
Java中的线程,即使工作单元,也是执行机制。从JDK5开始,把工作单元与执行机制分离开来。
- 工作单元:Runnable 和 Callable
- 执行机制:Executor 框架
1. Executor 框架简介
1.1 Executor 框架的两级调度模型
- 在HotSpot VM 的线程模型中,Java线程(java.lang.Thread) 被一对一的映射为本地操作系统的线程。Java线程的启动与销毁都与本地线程同步。操作系统会调度所有线程并将它们分配给可用的CPU。
- 在上层,Java使用多线程的程序,通常会将应用分解为若干任务,然后使用用户级别的调度器(Executor框架)将这些任务映射为对应数量的线程;
- 底层,操作系统会将这些线程映射到硬件处理器上,切下层硬件的调度并不受应用程序的控制。调度模型如下图
1.2 Executor框架的结构与成员
1. Excutor 框架的结构 -主要由3大部分组成
-
任务
- Runnable接口(无返回值)
- Callable<V>接口(有返回值)
-
任务的执行
执行机制的核心接口-Executor,以及实现Executor接口的ExecutorService,
Executor框架 中有两个关键类实现了ExecutorService:
-
ThreadPoolExecutor
线程池的实现类,执行被提交的线程、任务(Callable/Runnable 接口的实现类中的run()方法)
-
ScheduledThreadPoolExecutor
给定延迟或定期的执行任务(Callable/Runnable 接口的实现类中的run()方法)、命令。比Timer 更加灵活,强大。
-
异步执行的结果(返回值)
Executor框架的使用:
- 主线程(main线程)创建实现Runnable或者Callable<V> 接口的待执行任务对象。
- Executors可以将Runnable封装为Callable<V> {Executors.callable(Runnable task)/(Runnable task,result)}。
- Runnable接口对象可以交由ExexutorService执行 {ExecutorService.executor(Runnable r) {无返回值};或者把Runnable接口对象或Callable<V>接口对象交由ExecutorService执行 {ExecutorService.submit(Runnable r/Callable<V> t) 有返回值 Futrue接口的对象,现阶段JDK返回的是FutureTask};
- 最后,主线程(main线程)执行 FutrueTask.get()阻塞,等待任务执行完成,同时获取返回值。也可以执行FutureTask.cancel(boolean mayInterruptIfRunning)取消执行(参数表示如果正在执行是否取消)。
2. Executor框架的成员
主要成员: ThreadPoolExecutor(线程池)、ScheduldThreadPoolExecutor、Runnable接口、Future<V>接口、Callable<V>接口 以及 Executors工具类。
-
ThreadPoolExecutor
通常使用Executors 创建,Executors可以创建三种类型的ThreadPoolExecutor:SingleThreadExecuto、FixedThreadPool、CachedThreadPool
-
FixedThreadPool 创建固定线程数,适用于限制当前线程数量时,适用于负载较重的服务器。
Executor创建使用的API:
public static ExecutorService newFixedThreadPool(int nThreads); public static ExecutorService newFixedThreadPool(int nThreads, ThreaDFactory threadFactory);
-
SingleThreadExecutor 创建单个线程,任意时间点不会有多个线程是活动的,适用于需要保证顺序执行各任务的时候。
Executors创建API:
public static ExecutorService newSingleThreadPool(); public static ExecutorService newSingleThreadPool(ThreadFactory threadFactory);
-
CachedThreadPool 根据需要创建新线程,大小无界的线程池,适用于执行大量短期的异步任务时,或负载较轻的服务器。
Executors创建API:
public static ExecutorService newCachedThreadPool(); public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
-
ScheduledThreadPoolExecutor
使用Executors工厂类创建,Executors可以创建两种类型的ScheduldThreadPoolExecutor
-
ScheduledThreadPoolExecutor 包含若干个线程,适用于多个线程执行周期任务,同时限制执行的线程数量。
Executors 创建固定个数线程ScheduledThreadPoolExecutor 的API:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize); public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);
-
SingleThreadScheduledExecutor 之包含一个线程,适用于单个后台线程执行定时任务,同时保证顺序执行各个任务。
Executors 创建单个线程SingleScheduledExecutor 的API:
public static ScheduledExecutorService newSingleScheduledExecutor(int corePoolSize); public static ScheduledExecutorService newSingleScheduledExecutor(int corePoolSize, ThreadFactory threadFactory);
-
Future 接口
与其实现类FutureTask用于表示异步计算的结果。Runnable/Callable接口提交(submit)给ThreadPoolExecutor或者ScheduledThreadPoolExecutor时候,返回值为FutureTask对象、实现类Future接口的对象。
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
-
Runnable 和Callable 接口
都可以被线程池执行,Runnable 无返回值,Callable 有返回值。
Runnable可以使用工厂类Executors将其封装为Callble
Executors 对应API如下:
//将返回的Callable对象提交给线程池返回FutureTask对象,调用FutureTask.get(),返回null public static Callable<Object> callable(Runnable task); //同上提交,FutureTask.get(),返回result对象。 public static Callable<Object> callable(Runnable task, T result);
参考书籍
《Java并发编程的艺术》 -方腾飞 魏鹏 程晓明 著
以上是脚本宝典为你收集整理的初读《Java并发编程的艺术》-第十章:Executor框架 -10.1 Executor框架简介全部内容,希望文章能够帮你解决初读《Java并发编程的艺术》-第十章:Executor框架 -10.1 Executor框架简介所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。