谈到`Future<V>`,一般就是和接收线程任务执行结果有关,最常用的是其实现类`FutureTask<V>`,冰河大佬对`Future<V>`源码进行了解析,但是我并没有看懂他的意思。这块我准备把我理解的一些浅显知识记录一下
使用
- 手动创建线程,使用Callable方式
- 线程池submit方式
-
1.手动创建线程,使用Callable方式
@Test
public void testThreadFutureTask() throws ExecutionException, InterruptedException {
Callable callable = ()-> 1;
FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
Thread thread = new Thread(futureTask);
thread.start();
Integer integer = futureTask.get();
System.out.println(integer);
}
创建线程时无法直接将Callable扔进Thread中,Thread必须接收一个Runnable
- 于是可以将Callable封装成FuntureTask
可以得出一个结论,FuntureTask必定是Runnable的一个子类
2.线程池submit方式
@Test
public void testThreadPoolFutureTask() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> submit = executorService.submit(() -> 1);
System.out.println(submit.get());
executorService.shutdown();
}
线程池的
submit()
允许你直接丢一个Callable给他-
3.线程池execute方式
@Test
public void testThreadPoolFutureTask2() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
FutureTask<Integer> futureTask = new FutureTask<>(() -> {for(int i=0;i<Integer.MAX_VALUE;i++) {
System.out.println(i);
}; return 1;});
// execute没有返回值
executorService.execute(futureTask);
System.out.println(futureTask.get());
executorService.shutdown();
}
这种方式也要将Callable封装成
FutureTask<V>
因为execute()
方法不接收Callable<V>
类结构
FutureTask
实现了RunnableFuture
Runnable
又继承自Future
和Runnable
- 所以可以说,
FuntureTask
就是一个Runnable