java Callable与Future的详解及实例

时间:2021-12-10 15:48:22

java  CallableFuture

Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。

Callable的接口定义如下;

?
1
2
3
4
5
public interface Callable<V> {
 
   V  call()  throws Exception;
<span id="transmark"></span>
}

Callable和Runnable的区别如下:

I    Callable定义的方法是call,而Runnable定义的方法是run。

II   Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。

III  Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。 

Future 介绍

Future表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。Future的cancel方法可以取消任务的执行,它有一布尔参数,参数为 true 表示立即中断任务的执行,参数为 false 表示允许正在运行的任务运行完成。Future的 get 方法等待计算完成,获取计算结果

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import java.util.concurrent.Callable;
 
import java.util.concurrent.ExecutorService;
 
import java.util.concurrent.Executors;
 
import java.util.concurrent.Future;
 
/**
 
 * Callable 和 Future接口
 
 * Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
 
 * Callable和Runnable有几点不同:
 
 * (1)Callable规定的方法是call(),而Runnable规定的方法是run().
 
 * (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
 
 * (3)call()方法可抛出异常,而run()方法是不能抛出异常的。
 
 * (4)运行Callable任务可拿到一个Future对象,
 
 * Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
 
 * 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
 
 */
 
public class CallableAndFuture {
 
  public static class MyCallable implements Callable{
 
     private int flag = 0;
 
     public MyCallable(int flag){
 
         this.flag = flag;
 
     }
 
     public String call() throws Exception{
 
       if (this.flag == 0){
 
           return "flag = 0";
 
      }
 
      if (this.flag == 1){ 
 
        try {
 
          while (true) {
 
              System.out.println("looping.");
 
              Thread.sleep(2000);
 
          }
 
        } catch (InterruptedException e) {
 
               System.out.println("Interrupted");
 
        }
 
        return "false";
 
      } else
 
            throw new Exception("Bad flag value!");
 
      }
 
    }
 
  }
 
  public static void main(String[] args) {
 
    // 定义3个Callable类型的任务
 
    MyCallable task1 = new MyCallable(0);
 
    MyCallable task2 = new MyCallable(1);
 
    MyCallable task3 = new MyCallable(2);
 
    
 
    // 创建一个执行任务的服务
 
    ExecutorService es = Executors.newFixedThreadPool(3);
 
    try {
 
      // 提交并执行任务,任务启动时返回了一个Future对象,
 
      // 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作
 
      Future future1 = es.submit(task1);
 
      // 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
 
      System.out.println("task1: " + future1.get());
 
      
 
      Future future2 = es.submit(task2);
 
      // 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
 
      Thread.sleep(5000);
 
      System.out.println("task2 cancel: " + future2.cancel(true));
 
      
 
      // 获取第三个任务的输出,因为执行第三个任务会引起异常
 
      // 所以下面的语句将引起异常的抛出
 
      Future future3 = es.submit(task3);
 
      System.out.println("task3: " + future3.get());
 
    } catch (Exception e){
 
      System.out.println(e.toString());
 
    }
 
    // 停止任务执行服务
 
    es.shutdownNow();
 
  }
 
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!