• Java程序员必须掌握的线程知识-Callable和Future


    创建线程的两种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。这两种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。

    一、Runnable接口

    先看一下java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法:

    public interface Runnable {
        public abstract void run();
    }

    由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。

    二、Callable接口

    Callable接口位于java.util.concurrent包下,在它里面也只声明了一个方法,只不过这个方法叫做call()。

    public interface Callable<V> {
        V call() throws Exception;
    }

    可以看到,这是一个泛型接口,call()函数返回的类型就是传递进来的V类型。Callable接口可以看作是Runnable接口的补充,call方法带有返回值,并且可以抛出异常。

    三、FutureTask类

    如何获取Callable的返回结果呢?一般是通过FutureTask这个中间媒介来实现的。整体的流程是这样的:
    把Callable实例当作参数,生成一个FutureTask的对象,然后把这个对象当作一个Runnable,作为参数另起线程。

    3.1 FutureTask的结构

    3.2 FutureTask的启动

    由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行。下面以Thread包装线程方式启动来说明一下。

    /**
     * Created by gan on 2019/5/19 10:01.
     */
    public class FutureTaskAndCallableDemo {
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            Callable<Integer> callable = new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("计算线程正在努力的计算结果....");
                    TimeUnit.SECONDS.sleep(6);
                    return 100;
                }
            };
    
    
            FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
            Thread thread = new Thread(futureTask);
            thread.start();
    
            System.out.println("main线程干点别的任务...");
    
            Integer result = futureTask.get();
            System.out.println("从计算线程拿到的结果为: " + result);
    
        }
    }

    四、Future接口

    FutureTask继承体系中的核心接口是Future。Future的核心思想是:一个方法,计算过程可能非常耗时,等待方法返回,显然不明智。可以在调用方法的时候,立马返回一个Future,可以通过Future这个数据结构去控制方法f的计算过程。
    这里的控制包括:
    get方法:获取计算结果(如果还没计算完,也是必须等待的)
    cancel方法:还没计算完,可以取消计算过程
    isDone方法:判断是否计算完
    isCancelled方法:判断计算是否被取消

    参考链接: http://www.threadworld.cn/archives/39.html

               https://www.cnblogs.com/fengsehng/p/6048609.html

  • 相关阅读:
    网页链接在 什么时候 进行跳转到哪里?
    word中那些重要但是被人忽略的快捷键和长word文档的跳转
    如何在editplus中配置ctags?
    winsow xp不能安装软件, 提示"中断" 是因为设置了 软件限制策略
    firefox的plugin-container.exe进程如何关闭?
    thinkphp的url地址区分大小写?
    thinkphp单入口和多入口的访问方法
    什么时候使用tab键来对齐代码和代码的风格
    该不该用inline-block取代float? inline和float的区别?
    cad中关于点样式点的绘制
  • 原文地址:https://www.cnblogs.com/ganbo/p/10888286.html
Copyright © 2020-2023  润新知