美文网首页
每日一结——Future,FutureTask

每日一结——Future,FutureTask

作者: 奔向学霸的路上 | 来源:发表于2020-07-23 09:35 被阅读0次

Future

获取任务的执行结果,一般是搭配ExecutorService使用。

Future接口

image.png

获取单个线程的执行结果

  • 调用V Future.get()方法能够阻塞等待执行结果
  • V get(long timeout, TimeUnit unit)方法可以指定等待的超时时间
// 取消任务
boolean cancel(boolean mayInterruptIfRunning);

// 获取任务执行结果
V get() throws InterruptedException, ExecutionException;

// 获取任务执行结果,带有超时时间限制
V get(long timeout, TimeUnit unit) throws InterruptedException,                             ExecutionException,  TimeoutException;

// 判断任务是否已经取消
boolean isCancelled();

// 判断任务是否已经结束
boolean isDone();

FutureTask

使用场景:

  • 阻塞:Future是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作,get方法会阻塞,直到任务返回结果,也就是说,阻塞。
  • 在高并发环境下确保任务只执行一次(这个嗯。。。我觉得了解一下吧,感觉很牵强)

FutureTask类图

FutureTask类图

从类图可以看出FutureTask即拥有Runnable特性又有Future特性。

FutureTask方法

FutureTask方法图

AQS无非关注点在于:状态(业务主要逻辑控制)、队列(等待队列)、CAS(安全set值)

FutureTask构造函数

两个构造函数,入参分别是Runnable、Callable,我们知道Runnable没有返回值,这两个构造函数实际上都是转到Callable来实现返回值。

/**
     * Creates a {@code FutureTask} that will, upon running, execute the
     * given {@code Runnable}, and arrange that {@code get} will return the
     * given result on successful completion.
     *
     * @param runnable the runnable task
     * @param result the result to return on successful completion. If
     * you don't need a particular result, consider using
     * constructions of the form:
     * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
     * @throws NullPointerException if the runnable is null
     */
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }
    /**
     * Creates a {@code FutureTask} that will, upon running, execute the
     * given {@code Callable}.
     *
     * @param  callable the callable task
     * @throws NullPointerException if the callable is null
     */
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
image.png
  1. Callable执行的方法是call(),Runnable执行的方法是run()。其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,或者交给ExecuteService执行,而Callable则一般都是提交给ExecuteService来执行。
  2. Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
  3. call方法可以抛出异常,run方法不可以
  4. 运行Callable任务可以拿到一个Future对象,表示异步计算的结果,而且拿到的这个Future对象后,如果调用get()方法,当前线程会阻塞,直到此Callable的call方法执行完毕。

举例一(由Thread执行):

    public static void main(String[] args) {
        CountSum countSum = new CountSum();// 创建一个Callable对象
        FutureTask<Integer> futureTask = new FutureTask<>(countSum);// 创建FutureTask对象
        Thread thread = new Thread(futureTask);// 开启线程
        thread.start();
        try {
            int sum = futureTask.get();
            System.out.println("主线程获得求和结果:" + sum);
        } catch (Exception e) {
            e.printStackTrace();
            futureTask.cancel(true);
        }
    }

    static class CountSum implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            System.out.println("开始求和");
            int sum = 0;
            for (int i = 0; i < 10000; i++) {
                sum += i;
            }
            Thread.sleep(2000);
            System.out.println("求和结束");
            return sum;
        }

    }

执行结果:

开始求和
求和结束
主线程获得求和结果:49995000

举例二(Futuretask也可以使用ExecutorService执行)

public static void main(String[] args) {
        CountSum countSum = new CountSum();// 创建一个Callable对象
        FutureTask<Integer> futureTask = new FutureTask<>(countSum);// 创建FutureTask对象

        ExecutorService executorService = Executors.newCachedThreadPool();// 开启线程
        executorService.execute(futureTask);
        try {
            int sum = futureTask.get();
            System.out.println("主线程获得求和结果:" + sum);
        } catch (Exception e) {
            e.printStackTrace();
            futureTask.cancel(true);
        } finally {
            executorService.shutdown();
        }
    }

参考:https://www.jianshu.com/p/16d6f0a22111
https://www.toutiao.com/i6847669587702612492/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1595402336&app=news_article&utm_source=weixin&utm_medium=toutiao_android&use_new_style=1&req_id=202007221518550100140481441F0A51AE&group_id=6847669587702612492

相关文章

网友评论

      本文标题:每日一结——Future,FutureTask

      本文链接:https://www.haomeiwen.com/subject/contlktx.html