Java多线程与并发之Callable接口-------是什么,怎么用

面试题:几种方式获得多线程?

此时如果你答两种:Runnable和继承Thread,这是不行的,正确答案应该是:

  • 传统的是继承thread类和实现runnable接口
  • JDK1.5 以后又有通过实现callable接口和线程池获得

Callable和Runnable对比

我们都熟悉Runnable接口,只要继承了这个类,并重写其Run方法,就可以通过Thread的构造器传入Runnable实例来启动一个多线程:

class MyThread1 implements Runnable{

    @Override
    public void run() {
        System.out.println("lalala");
    }
}

而Callable是怎么做的呢:

class MyThread implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("....come in here");
        return 1024;
    }
}

区别如下:

  1. Callable有返回值,Runnable没有返回值
  2. Callable抛出异常,Runnable不抛异常
  3. Callable实现的是Call方法,Runnable实现的是Run方法

总结:Callable接口,是Runable接口的增强版。同样用Call()方法作为线程的执行体,增强了之前的run()方法。因为call方法可以有返回值,也可以声明抛出异常。


Callable怎么用?

如果你想用之前的流程,通过Thread类的构造器来创建线程,然后start那么就错了。我们看一下Thread类的构造器:
在这里插入图片描述
通过构造方法可以看出:Thread类并不允许我们传入一个Callable接口来创建线程,那么应该怎么做呢:答案是找一个中间人,这个中间人可以将Callable接口和Runnable接口关联起来


FutureTask 是什么

  • 字面理解:未来的任务
  • 用它就干一件事,异步调用
  • 在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,
    当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。
  • 老师上着课,口渴了,去买水不合适,讲课线程继续,我可以单起个线程找班长帮忙买水,水买回来了放桌上,我需要的时候再去get。

FutureTask是Future接口的实现类,用它能帮我们解决异步调用的问题。

java5提供了Future接口来代表Callable接口里的call()方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现了Future接口,并实现了Runnable接口,所以这样可以作为Thread的target


看一下FutureTask的继承关系:
在这里插入图片描述
发现它同时实现了Runnable接口,并且看一下它的构造器:

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

那么只要我们通过FutureTask对象,就可以传入我们的Callable接口,从而通过Thread来启动一个线程了。


实例代码

public static void main(String[] args) throws ExecutionException, InterruptedException {

        FutureTask<Integer> futureTask = new FutureTask<>(new MyThread2());

        new Thread(futureTask,"zhang3").start();


        while(!futureTask.isDone()){
            System.out.println("***wait");
        }
        System.out.println(futureTask.get());
        System.out.println(Thread.currentThread().getName()+" come over");
    }

class MyThread2 implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"come in callable");
        return 200;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值