获取子线程的执行结果

创建线程有哪几种方式

  • 继承Thread类(Thread类也是实现Runnable接口);
public
class Thread implements Runnable {
  • 实现Runnable接口;
  • 通过线程池创建线程池;
  • 实现Callable接口与ExecutorService结合使用

因为Java的类是单继承,接口可以多实现。所以在创建子任务的时候,更多的是选择实现接口。线程池的出现为了让线程可以很好的复用,减少系统开销(线程的启动、销毁等过程是比较复杂的),同时也统一把线程管理起来。

Runnable不足?

现Runnable接口中的run()方法:

public abstract void run();

通过源码中的run方法可以看出,run方法没有返回值。如果我们需要接受子线程返回结果,此时该接口已经不满足我们的需求了。那么怎么接受子线程返回的结果呢?此时就需要通过Callable接口创建线程了。同样的先看看过Callable接口中的方法定义

Callable接口中的call()方法

 V call() throws Exception;

和run()对比,可以看出该方法支持返回值,支持向上抛出异常。

Callable接口的简单实例

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(new Task());//submit结果
        String result = future.get();//取出子线程运行结果
        System.out.println("子任务的执行结果:"+result);//子任务的执行结果:1995-01-01
        executorService.shutdown();
    }

    private static class Task implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "1995-01-01";
        }
    }

FutureTask获取结果

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        //通过Callable实例构建FutureTask实例
        FutureTask<String> futureTask = new FutureTask<>(new Task());
        //提交任务到线程池
        executorService.execute(futureTask);
        //取出子线程运行结果
        String result = futureTask.get();
        System.out.println("子任务的执行结果:" + result);//子任务的执行结果:1995-01-02
    }

    private static class Task implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "1995-01-02";
        }
    }

Future接口中方法
获取子线程的执行结果_第1张图片
其实根据命名,已经可以推测出这些方法的作用了,下面主要记录一些注意点

  • get():获取Callable接口返回的结果,假设主线程调用了get()方法,但是此时子线程还没有执行完毕(即还没有返回结果),此时主线程会被阻塞,知道call()方法返回了结果。
  • get(long timeout, TimeUnit unit):在get()的基础上加上超时时间;
  • isDone():判断子线程是否执行完毕;
  • cancel(boolean mayInterruptIfRunning):取消线程

取消线程坑时可能遇到的几种情况
1.线程还没有执行:返回true

2.线程已经执行完毕或者取消了,返回false;

3.线程已经开始执行了,此时根据设置的mayInterruptIfRunning来判断是否直接取消任务。mayInterruptIfRunning为ture适用于子任务有逻辑处理中断。false适用于子线程没有能力处理中断;需求是需要等待已经开始的线程执行完毕。

FutureTask
获取子线程的执行结果_第2张图片
FutureTask:实现了Runnable和Future接口,表示异步计算的结果。

你可能感兴趣的:(Java多线程与高并发)