Executor 框架
Java的线程既是工作单元,也是执行机制。从JDK5开始,把工作单元与执行机制分离开来。工作单元包括Runnable
和Callable
,而执行机制由Executor
框架提供。
Executor 框架简介
在HotSpot VM
的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当该Java线程终止时,这个操作系统线程也被收回。操作系统会调度所有线程并将他们分配给可用的CPU。如图
Executor 框架结构
主要由3大部分组成:
- 任务:包括被执行任务需要实现的接口:
Runnable
接口和Callable
接口 - 任务的执行:包括任务执行机制的核心接口
Executor
,以及继承自它的ExecutorService
接口。有两个关键类实现了ExecutorService
接口(ThreadPoolExecutor
和ScheduledThreadPoolExecutor
)。 - 异步计算的结果:包括接口
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)给ThreadPoolExecutor
或ScheduledThreadPoolExecutor
时,ThreadPoolExecutor
或ScheduledThreadPoolExecutor
会向我们返回一个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接口
这两个接口的实现类都可以被ThreadPoolExecutor
或ScheduledThreadPoolExecutor
执行,最后一个方法没有返回值,其他均可以通过得到的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)
此时将这种转换过的对象交给ThreadPoolExecutor
或ScheduledThreadPoolExecutor
执行时,第一个种转换方法不会有返回值。
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 框架的更多相关文章
- java并发编程(十七)Executor框架和线程池
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...
- Executor框架(转载)
Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...
- Java并发和多线程(二)Executor框架
Executor框架 1.Task?Thread? 很多人在学习多线程这部分知识的时候,容易搞混两个概念:任务(task)和线程(thread). 并发编程可以使我们的程序可以划分为多个分离的.独立运 ...
- java并发编程-Executor框架
Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...
- 戏(细)说Executor框架线程池任务执行全过程(上)
一.前言 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不 ...
- 戏(细)说Executor框架线程池任务执行全过程(下)
上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现Th ...
- Java并发——线程池Executor框架
线程池 无限制的创建线程 若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时: 线程生命周期的开销非常高 资源消耗 稳定性 引入线程池 任务是一组逻辑 ...
- Java Executor 框架学习总结
大多数并发都是通过任务执行的方式来实现的.一般有两种方式执行任务:串行和并行. class SingleThreadWebServer { public static void main(String ...
- Executor框架
Executor框架是指java5中引入的一系列并发库中与executor相关的功能类,包括Executor.Executors.ExecutorService.CompletionService. ...
- Java Executor 框架
Java Executor 框架 Executor框架是指java5中引入的一系列并发库中与executor相关的功能类,包括Executor.Executors. ExecutorService.C ...
随机推荐
- [ios]ios画线 使用CGContextRef,CGPath和UIBezierPath来绘画
参考 :http://www.mgenware.com/blog/?p=493 这三种东西:CGContextRef,CGPath和UIBezierPath.本质上都是一样的,都是使用Quartz来绘 ...
- 使用NativeExtension向AIR app 添加Activity和BroadCastReceiver(2)
开发: Android项目 新建一个针对NativeExtension的Android项目,实现相应的FREContext,FREExtension和FREFunction等方法,同时新建一个Acti ...
- 【Robot Framework 项目实战 01】使用 RequestsLibrary 进行接口测试
写在前面 本文我们一起来学习如何使用Robot Framework 的RequestsLibrary库,涉及POST.GET接口测试,RF用例分层封装设计等内容. 接口 接口测试是我们最常见的测试类型 ...
- C# int.ToString() 常用参数说明
C#中int类型的ToString()方法有个重载是输入一个字符串,这个字符串可以对int进行部分格式化操作,如上.
- [.NET开发] C# BigInteger 处理超大整型数字
今天遇到一个要处理XSD中Integer的数值区间的计算的问题,Integer这个类型的值区间理论上是可没有边界的,假设目前的值是1.5E+10000, 这个数字已经达到double和Int64都无法 ...
- GetTitleAndUrl
Sub GetTitleAndUrl() Dim strText As String Dim i As Long Dim OneA Dim IsContent As Boolean Dim PageI ...
- 20170706wdVBA正则表达式提取题目
Public Sub GetContents() Dim Reg As Object Dim Matches As Object Dim OneMatch As Object Dim Index As ...
- javaScript 的 map() reduce() foreach() filter()
map(映射), reduce(规约), forEach(遍历), filter(过滤),它们都是高阶函数,都是以传入不同的函数来以不同的方式操作数组元.ie都不支持 一.map方法 *概述 map( ...
- Confluence 6 使用 LDAP 授权连接一个内部目录 - 服务器设置
名字(Name) 名字的描述将会帮助你在目录中识别.例如: Internal directory with LDAP Authentication Corporate LDAP for Authent ...
- bzoj 1267 Kth Number I (点分治,堆)
超级钢琴的树上版本, 类似做法即可, 只不过区间转为dfs序了, 用点分求一下, 复杂度$O(nlog^2n)$ #include <iostream> #include <algo ...