1. 谈到`Future<V>`,一般就是和接收线程任务执行结果有关,最常用的是其实现类`FutureTask<V>`,冰河大佬对`Future<V>`源码进行了解析,但是我并没有看懂他的意思。这块我准备把我理解的一些浅显知识记录一下

使用

  • 手动创建线程,使用Callable方式
  • 线程池submit方式
  • 线程池executor方式

    1.手动创建线程,使用Callable方式

    1. @Test
    2. public void testThreadFutureTask() throws ExecutionException, InterruptedException {
    3. Callable callable = ()-> 1;
    4. FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
    5. Thread thread = new Thread(futureTask);
    6. thread.start();
    7. Integer integer = futureTask.get();
    8. System.out.println(integer);
    9. }
  • 创建线程时无法直接将Callable扔进Thread中,Thread必须接收一个Runnable

  • 于是可以将Callable封装成FuntureTask
  • 可以得出一个结论,FuntureTask必定是Runnable的一个子类

    2.线程池submit方式

    1. @Test
    2. public void testThreadPoolFutureTask() throws ExecutionException, InterruptedException {
    3. ExecutorService executorService = Executors.newSingleThreadExecutor();
    4. Future<Integer> submit = executorService.submit(() -> 1);
    5. System.out.println(submit.get());
    6. executorService.shutdown();
    7. }
  • 线程池的submit()允许你直接丢一个Callable给他

  • 并且会返回一个Future接收返回值信息

    3.线程池execute方式

    1. @Test
    2. public void testThreadPoolFutureTask2() throws ExecutionException, InterruptedException {
    3. ExecutorService executorService = Executors.newSingleThreadExecutor();
    4. FutureTask<Integer> futureTask = new FutureTask<>(() -> {for(int i=0;i<Integer.MAX_VALUE;i++) {
    5. System.out.println(i);
    6. }; return 1;});
    7. // execute没有返回值
    8. executorService.execute(futureTask);
    9. System.out.println(futureTask.get());
    10. executorService.shutdown();
    11. }
  • 这种方式也要将Callable封装成FutureTask<V>因为execute()方法不接收Callable<V>

    类结构

    image.png

  • FutureTask实现了RunnableFuture

  • Runnable又继承自FutureRunnable
  • 所以可以说,FuntureTask 就是一个 Runnable