java线程之——FutureTask

3 篇文章 0 订阅
2 篇文章 0 订阅

一、FutureTask的实现

FutureTask实现了RunnableFuture,既即实现Runnable接口和Future接口。所以FutureTask实现run方法,以及Future接口的一系列计算结果方法

二、构造方法

FutureTask有两个构造方法,分别为一个参数和两个参数,如下图:

一个参数构造器传入一个Callable实现,需要返回参数;

第二个构造器第一个参数传入Runnable实现,不需要返回参数,但是需要再第二个参数指定返回值;

如下:

  public static void test1() throws Exception {
    // FutureTask封装一个线程
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      Thread.sleep(3000);
      throw new Exception("神奇");
      // return "工作完成";
    });
    // run运行线程,不会返回结果,线程异常不会被抛出,get时才会抛出异常
    future.run();
    // get等待任务执行完成,并返回结果
    System.out.println(future.get());
  }

  public static void test2() throws Exception {
    FutureTask<String> futureTask = new FutureTask<>(() -> System.out.println("work"), "OK");
    futureTask.run();
    System.out.println(futureTask.get());
  }

 

三、方法

1、run():同线程的run方法,执行FutureTask的线程run方法,该方法不会抛出线程内部的异常。如果在之前FutureTask已被调用cancle方法取消,会抛出CancellationException。注意,FutureTask直接执行run方法,会阻塞等待线程执行完成,如下:

public static void testRun() throws Exception {
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      Thread.sleep(5000);
      return "工作完成";
    });
    future.run();
    System.out.println("主线程被阻塞");
    System.out.println(future.get());
}

如果需要异步执行,需要用new Thread()去跑或者通过线程池执行,如下:

  public static void testRun() throws Exception {
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      Thread.sleep(5000);
      return "工作完成";
    });
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.submit(future);
    System.out.println("主线程不被阻塞");
    System.out.println(future.get());
    System.out.println("主线程阻塞,get等线程返回结果");
  }

2、cancle方法:尝试取消执行此任务,有一个布尔值的参数mayInterruptIfRunning,此参数决定是否可以终止正在执行中的线程。

  • mayInterruptIfRunning为true,可以终止正在执行中的线程,返回true;
    public static void testCancle() throws Exception {
        FutureTask<String> future = new FutureTask<>(() -> {
          System.out.println("work...");
          for (int i = 0; i < 10; i++) {
            Thread.sleep(1000);
            System.out.println(i);
          }
          System.out.println("工作完成!!!!");
          return "工作完成";
        });
        Thread thread = new Thread(future);
        thread.start();
        Thread.sleep(1000);
        System.out.println("取消正在执行的FutureTask");
        //true,会终止正在运行的线程
        System.out.println(future.cancel(true));
        System.out.println(future.isCancelled());
      }

     

  • mayInterruptIfRunning为false,不能终止正在执行中的线程,返回false;
    public static void testCancle() throws Exception {
        FutureTask<String> future = new FutureTask<>(() -> {
          System.out.println("work...");
          for (int i = 0; i < 10; i++) {
            Thread.sleep(1000);
            System.out.println(i);
          }
          System.out.println("工作完成!!!!");
          return "工作完成";
        });
        Thread thread = new Thread(future);
        //false,如果线程已经开始执行,当前任务是不会被终止,但是仍然返回true
        System.out.println("取消还未执行的FutureTask");
        System.out.println(future.cancel(false));
        System.out.println(future.isCancelled());
        thread.start();
    }
  • 如果线程已被cancle,再次cancle将返回false;
     
      public static void testCancle() throws Exception {
        FutureTask<String> future = new FutureTask<>(() -> {
          System.out.println("work...");
          Thread.sleep(5000);
          return "工作完成";
        });
        new Thread(future).start();
        System.out.println("取消正在执行的FutureTask");
        System.out.println(future.cancel(true));
        System.out.println(future.get());
      }

     

3、get方法:等待计算完成,然后检索其结果,这个方法会阻塞主线程,直到run执行完成并返回值。还可以设置最长等待时间,超过将抛出TimeoutException;计算引发异常抛出ExecutionException;当前线程在等待时中断抛出InterruptedException;计算被取消抛出CancellationException。

  public static void testTimeoutException() throws Exception {
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      Thread.sleep(5000);
      System.out.println("工作完成!!!!");
      return "工作完成";
    });
    new Thread(future).start();
    System.out.println(future.get(1, TimeUnit.SECONDS));
  }

  public static void testCancellationException() throws Exception {
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      Thread.sleep(5000);
      System.out.println("工作完成!!!!");
      return "工作完成";
    });
    new Thread(future).start();
    Thread.sleep(1000);
    System.out.println(future.cancel(true));
    System.out.println(future.get(1, TimeUnit.SECONDS));
  }

  public static void testGetExecutionException() throws Exception {
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      throw new Exception("出错啦");
    });
    new Thread(future).start();
    System.out.println(future.get());
  }

  public static void testInterruptedException() throws Exception {
    FutureTask<String> future = new FutureTask<>(() -> {
      System.out.println("work...");
      Thread.sleep(5000);
      return "工作完成";
    });
    Thread thread = new Thread(future);
    thread.start();
    thread.interrupt();
    System.out.println(future.get());
  }

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值