有一段时间前,我写了一篇关于 Java Callable Future接口的文章,我们可以用来获得线程的同时处理的好处,以及它们能够返回呼叫程序的值。 FutureTask是未来接口的基本具体实现,并提供非同步处理。它包含启动和取消任务的方法,以及可以返回未来任务的状态的方法,就像它已经完成或取消一样。我们需要一个可呼叫的对象来创建未来任务,然后我们可以使用 Java Thread Pool Executor来实现这些过程。让我们看看未来任务的例子用一个简单的程序。由于未来任务需要一个可
1package com.journaldev.threads;
2
3import java.util.concurrent.Callable;
4
5public class MyCallable implements Callable<String> {
6
7 private long waitTime;
8
9 public MyCallable(int timeInMillis){
10 this.waitTime=timeInMillis;
11 }
12 @Override
13 public String call() throws Exception {
14 Thread.sleep(waitTime);
15 //return the thread name executing this callable task
16 return Thread.currentThread().getName();
17 }
18
19}
以下是 FutureTask 方法的示例,并显示了常用的 FutureTask 方法。
1package com.journaldev.threads;
2
3import java.util.concurrent.ExecutionException;
4import java.util.concurrent.ExecutorService;
5import java.util.concurrent.Executors;
6import java.util.concurrent.FutureTask;
7import java.util.concurrent.TimeUnit;
8import java.util.concurrent.TimeoutException;
9
10public class FutureTaskExample {
11
12 public static void main(String[] args) {
13 MyCallable callable1 = new MyCallable(1000);
14 MyCallable callable2 = new MyCallable(2000);
15
16 FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
17 FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
18
19 ExecutorService executor = Executors.newFixedThreadPool(2);
20 executor.execute(futureTask1);
21 executor.execute(futureTask2);
22
23 while (true) {
24 try {
25 if(futureTask1.isDone() && futureTask2.isDone()){
26 System.out.println("Done");
27 //shut down executor service
28 executor.shutdown();
29 return;
30 }
31
32 if(!futureTask1.isDone()){
33 //wait indefinitely for future task to complete
34 System.out.println("FutureTask1 output="+futureTask1.get());
35 }
36
37 System.out.println("Waiting for FutureTask2 to complete");
38 String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
39 if(s !=null){
40 System.out.println("FutureTask2 output="+s);
41 }
42 } catch (InterruptedException | ExecutionException e) {
43 e.printStackTrace();
44 }catch(TimeoutException e){
45 //do nothing
46 }
47 }
48
49 }
50
51}
当我们运行程序时,你会注意到它不会打印任何东西一段时间,因为FutureTask的get()
方法等待任务完成,然后返回输出对象。
1FutureTask1 output=pool-1-thread-1
2Waiting for FutureTask2 to complete
3Waiting for FutureTask2 to complete
4Waiting for FutureTask2 to complete
5Waiting for FutureTask2 to complete
6Waiting for FutureTask2 to complete
7FutureTask2 output=pool-1-thread-2
8Done
因此,FutureTask 没有任何好处,但当我们想要超越一些Future 界面方法时,它很有用,而不希望实现Future 界面的每个方法。