Runnable、Future 和 RunnableFuture

文章目录
  1. 1. Runnable
  2. 2. Future
  3. 3. RunnableFuture
  4. 4. 区别和优缺点
  5. 5. 常见使用场景
  6. 6. 注意事项

Runnable

  • 定义Runnable 是 Java 中表示可执行任务的接口,通常用于执行没有返回值的任务。
  • 特点:只有一个 run() 方法,无法获取任务执行结果。

Future

  • 定义Future 是 Java 中表示异步计算结果的接口,用于表示一个可能还没有完成的计算。

  • 特点

    • 提供 get() 方法来获取计算结果,该方法可能会阻塞直到计算完成。
    • 通过 isDone() 方法可以检查计算是否完成。
    • 提供 cancel() 方法来取消计算。

RunnableFuture

  • 定义RunnableFuture 是继承自 RunnableFuture 的接口,用于表示一个可运行的、有结果的任务。
  • 特点:兼具了 RunnableFuture 的特性,既可以作为任务执行,又可以获取任务执行结果。

区别和优缺点

  • Runnable:用于表示没有返回值的任务,适用于简单的并发场景。
  • Future:用于表示异步计算的结果,可获取计算结果和取消计算。
  • RunnableFuture:兼具 RunnableFuture 的特性,适用于希望任务能够被取消、并且能够返回结果的场景。

常见使用场景

  • Runnable:适用于执行简单的、无返回值的任务。
  • Future:适用于需要获取异步计算结果的场景。
  • RunnableFuture:适用于希望任务能够被取消、并且能够返回结果的场景。

注意事项

  • 对于使用 Future 的场景,需要注意在获取计算结果时可能会阻塞,需要谨慎使用。

这些接口和类提供了在多线程环境中进行任务调度和管理的基本工具,根据具体需求选择合适的接口和实现类可以更好地满足不同的并发场景。

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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
* author: leek
* dataTime: 2023年12月15日 下午4:16
*/
public class TaskFeatureOverview {
static ExecutorService executorService =
new ThreadPoolExecutor(
11, 33,
2L, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(11),
new ThreadFactoryBuilder().build());
static Executor executor = new ThreadPoolExecutor(
11, 33,
2L, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(22),
new ThreadFactoryBuilder().build());


@Test
public void t1_runable() throws InterruptedException {
List<String> strings = new ArrayList<>(Arrays.asList("dd", "aa", "ee"));
CountDownLatch count = new CountDownLatch(1);
((Runnable) () -> {
System.out.println("匿名内部类");
System.out.println(strings.toString());
strings.add("ww");

}).run();
executorService.execute(() -> {
System.out.println("匿名内部类+++");
System.out.println(strings.toString());
strings.add("qq");
count.countDown();

});
System.out.println(strings.toString());
count.await();
System.out.println(strings.toString());
}

@Test
public void t1_callable_sync() throws Exception {
List<String> strings = new ArrayList<>(Arrays.asList("dd", "aa", "ee"));
CountDownLatch count = new CountDownLatch(1);


Future<Object> future = executorService.submit((Callable<Object>) () -> {
strings.add("ww");
Thread.sleep(1000);
count.countDown();
return strings.size();
});
// 阻塞等待数据
System.out.println("第一次获取:" + future.get());

count.await();
// 阻塞等待数据
System.out.println("第二次获取:" + future.get());

}

@Test
public void t1_callable_async() throws Exception {
List<String> strings = new ArrayList<>(Arrays.asList("dd", "aa", "ee"));
CountDownLatch count = new CountDownLatch(1);


Future<Object> future = executorService.submit((Callable<Object>) () -> {
strings.add("ww");
Thread.sleep(1000);
count.countDown();
return strings.size();
});
System.out.println("第一次获取:" + future.get());

count.await();
System.out.println("第二次获取:" + future.get());

}

@Test
public void t1_future() {
Class<CompletableFuture> completableFutureClass = CompletableFuture.class;


}

@Test
public void t1_RunnableFuture() {
Class<FutureTask> futureTaskClass = FutureTask.class;


}


@Test
public void t1_Sick_skills() {
List<Object> list = new ArrayList<>();
list.stream().forEach(id -> CompletableFuture.supplyAsync(()
-> {
return id;
}).whenComplete((s, e) -> {

}));


CompletableFuture[] completableFutures = list.stream().map(id -> CompletableFuture.supplyAsync(()
-> {
return id;
}).whenComplete((s, e) -> {

})).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(completableFutures).join();
}

/**
* @Async
* public Future<String> getValue() {
* // ...
* return result;
* }
* 获取future后异步调用:
*
* java
*
* Copy code
*
* Future<String> future = getValue();
* future.get() //异步等待结果*
*/
}
package com.lee.demo.thread;/**
* @author simba@onlying.cn
* @date 2023年12月15日 下午4:16
*/

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
* author: leek
* dataTime: 2023年12月15日 下午4:16
*/
public class TaskFeatureOverview {
static ExecutorService executorService =
new ThreadPoolExecutor(
11, 33,
2L, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(11),
new ThreadFactoryBuilder().build());
static Executor executor = new ThreadPoolExecutor(
11, 33,
2L, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(22),
new ThreadFactoryBuilder().build());


@Test
public void t1_runable() throws InterruptedException {
List<String> strings = new ArrayList<>(Arrays.asList("dd", "aa", "ee"));
CountDownLatch count = new CountDownLatch(1);
((Runnable) () -> {
System.out.println("匿名内部类");
System.out.println(strings.toString());
strings.add("ww");

}).run();
executorService.execute(() -> {
System.out.println("匿名内部类+++");
System.out.println(strings.toString());
strings.add("qq");
count.countDown();

});
System.out.println(strings.toString());
count.await();
System.out.println(strings.toString());
}

@Test
public void t1_callable_sync() throws Exception {
List<String> strings = new ArrayList<>(Arrays.asList("dd", "aa", "ee"));
CountDownLatch count = new CountDownLatch(1);


Future<Object> future = executorService.submit((Callable<Object>) () -> {
strings.add("ww");
Thread.sleep(1000);
count.countDown();
return strings.size();
});
// 阻塞等待数据
System.out.println("第一次获取:" + future.get());

count.await();
// 阻塞等待数据
System.out.println("第二次获取:" + future.get());

}

@Test
public void t1_callable_async() throws Exception {
List<String> strings = new ArrayList<>(Arrays.asList("dd", "aa", "ee"));
CountDownLatch count = new CountDownLatch(1);


Future<Object> future = executorService.submit((Callable<Object>) () -> {
strings.add("ww");
Thread.sleep(1000);
count.countDown();
return strings.size();
});
System.out.println("第一次获取:" + future.get());

count.await();
System.out.println("第二次获取:" + future.get());

}

@Test
public void t1_future() {
Class<CompletableFuture> completableFutureClass = CompletableFuture.class;


}

@Test
public void t1_RunnableFuture() {
Class<FutureTask> futureTaskClass = FutureTask.class;


}


@Test
public void t1_Sick_skills() {
List<Object> list = new ArrayList<>();
list.stream().forEach(id -> CompletableFuture.supplyAsync(()
-> {
return id;
}).whenComplete((s, e) -> {

}));


CompletableFuture[] completableFutures = list.stream().map(id -> CompletableFuture.supplyAsync(()
-> {
return id;
}).whenComplete((s, e) -> {

})).toArray(CompletableFuture[]::new);
CompletableFuture.allOf(completableFutures).join();
}

/**
* @Async
* public Future<String> getValue() {
* // ...
* return result;
* }
* 获取future后异步调用:
*
* java
*
* Copy code
*
* Future<String> future = getValue();
* future.get() //异步等待结果*
*/
}

参考链接:
如何合理估算 Java 线程池大小:综合指南