11##1 . Callable
2- 泛型接口,用于获取线程执行完的结果
2+ 泛型接口,用于获取线程执行完的结果,Callable的声明如下
33
4- Callable 接口类似于Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而Callable返回结果并且可能抛出异常的任务
4+ ``` java
5+ public interface Callable <V> {
6+ // 返回 V 类型的结果
7+ V call () throws Exception ;
8+ }
9+ ```
10+
11+ Callable 接口类似于Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而Callable是可返回结果并且可以抛出异常的任务
512
613``` java
714public class MyCallable implements Callable {
@@ -45,10 +52,27 @@ public class CallableDemo {
4552```
4653
4754##2 . Future
55+
56+ Future 为线程池提供了一个可管理的任务标准,它提供了对Runnable或Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作
57+
4858Future 接口表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用get()方法来获取结果,如有必要,计算完成前可以阻塞此方法
4959
50- Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的。Callable要采用ExecutorService的submit()方法提交,返回的future对象可以取消任务
60+ Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的。Callable要采用ExecutorService的submit()方法提交,返回的future对象可以取消任务。Future声明如下
5161
62+ ``` java
63+ public interface Future <V> {
64+ boolean cancel (boolean var1 );
65+ // 该任务是否已经取消
66+ boolean isCancelled ();
67+ // 判断是否已经完成
68+ boolean isDone ();
69+ // 获取结果,该方法会阻塞
70+ V get () throws InterruptedException , ExecutionException ;
71+ // 获取结果,如果还未完成那么等待,直到timeout或返回结果,该方法会阻塞
72+ V get (long var1 , TimeUnit var3 ) throws InterruptedException , ExecutionException , TimeoutException ;
73+ }
74+ ```
75+ Future的简单使用
5276``` java
5377// 创建线程池对象
5478ExecutorService pool = Executors . newFixedThreadPool(2 );
@@ -57,16 +81,20 @@ Future<Integer> future = pool.submit(new MyCallable(100));
5781Integer i1 = future. get();
5882pool. shutdown();
5983```
84+ Future常用方法
6085
61- | 方法声明 | 功能描述 |
62- | :----------- | :----- |
63- | cancel() | 取消任务 |
64- | isCanceled() | 任务是否取消 |
65- | isDone() | 任务是否完成 |
66- | get() | 获取结果 |
86+ | 方法声明 | 功能描述 |
87+ | :----------- | :----------------------- |
88+ | cancel() | 取消任务 |
89+ | isCanceled() | 任务是否取消 |
90+ | isDone() | 任务是否完成 |
91+ | get() | 获取结果,get()方法会阻塞,直到任务返回结果 |
92+ | set() | 设置结果 |
6793
6894## 3. FutureTask
6995
96+ Future只是定义了一些接口规范,而FutureTask则是它的实现类
97+
7098``` java
7199public class FutureTask <V> implements RunnableFuture<V > {
72100 // 代码省略
@@ -77,7 +105,117 @@ public interface RunnableFuture<V> extends Runnable, Future<V>{
77105}
78106```
79107
108+ FutureTask会像Thread包装Runnable那样对Runnable和Callable<V >进行包装,Runnable和Callable由构造函数注入
109+
110+ ``` java
111+ public FutureTask(Callable<V > callable) {
112+ if (callable == null )
113+ throw new NullPointerException ();
114+ this . callable = callable;
115+ this . state = NEW ; // ensure visibility of callable
116+ }
117+ ```
118+
119+ ``` java
120+ public FutureTask(Runnable runnable, V result) {
121+ this . callable = Executors . callable(runnable, result);
122+ this . state = NEW ; // ensure visibility of callable
123+ }
124+ ```
125+
126+ 由于FutureTask实现了Runnable,因此,它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行,并且还可以直接通过get()方法获取执行结果,该方法会阻塞,直到结果返回。因此,FutureTask既是Future、Runnable,又是包装了Callable,它是两者的合体
127+
128+ ``` java
129+ public class FutureDemo {
130+ // 线程池
131+ static ExecutorService mExecutor = Executors . newSingleThreadExecutor();
132+
133+ // main函数
134+ public static void main (String [] args ) {
135+ try {
136+ futureWithRunnable();
137+ futureWithCallable();
138+ futureTask();
139+ } catch (Exception e) {
140+ }
141+ }
142+
143+ /**
144+ * 其中Runnable实现的是void run()方法,无返回值;Callable实现的是 V
145+ * call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下
146+ * ,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
147+ */
148+ private static void futureWithRunnable () throws InterruptedException , ExecutionException {
149+ // 提交runnable则没有返回值, future没有数据
150+ Future<?> result = mExecutor. submit(new Runnable () {
151+
152+ @Override
153+ public void run () {
154+ fibc(20 );
155+ }
156+ });
157+
158+ System . out. println(" future result from runnable : " + result. get());
159+ }
160+
161+ private static void futureWithCallable () throws InterruptedException , ExecutionException {
162+ /**
163+ * 提交Callable, 有返回值, future中能够获取返回值
164+ */
165+ Future<Integer > result2 = mExecutor. submit(new Callable<Integer > () {
166+ @Override
167+ public Integer call () throws Exception {
168+ return fibc(20 );
169+ }
170+ });
171+
172+ System . out. println(" future result from callable : "
173+ + result2. get());
174+ }
175+
176+ private static void futureTask () throws InterruptedException , ExecutionException {
177+ /**
178+ * FutureTask则是一个RunnableFuture<V>,即实现了Runnbale又实现了Futrue<V>这两个接口,
179+ * 另外它还可以包装Runnable(实际上会转换为Callable)和Callable
180+ * <V>,所以一般来讲是一个符合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行
181+ * ,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。
182+ */
183+ FutureTask<Integer > futureTask = new FutureTask<Integer > (
184+ new Callable<Integer > () {
185+ @Override
186+ public Integer call () throws Exception {
187+ return fibc(20 );
188+ }
189+ });
190+ // 提交futureTask
191+ mExecutor. submit(futureTask);
192+ System . out. println(" future result from futureTask : "
193+ + futureTask. get());
194+ }
195+
196+ // 效率底下的斐波那契数列, 耗时的操作
197+ private static int fibc (int num ) {
198+ if (num == 0 ) {
199+ return 0 ;
200+ }
201+ if (num == 1 ) {
202+ return 1 ;
203+ }
204+ return fibc(num - 1 ) + fibc(num - 2 );
205+ }
206+ }
207+ ```
208+
209+ 输出结果
210+
211+ ```
212+ future result from runnable : null
213+ future result from Callable : 6765
214+ future result from futureTask : 6765
215+ ```
216+
80217##4 . CompletionService
218+
81219CompletionService用于提交一组Callable任务,其take()方法返回已完成的一个Callable任务对应的Future对象。
82220
83221示例:这里数据的获取好比同时种了好几块地的麦子,然后等待收割,秋收时,哪块先熟,先收割哪块
0 commit comments