Callable和FutureTask的用途

创建线程

创建线程有四种方法:

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口
  4. 使用线程池创建线程

继承Thread类

public class Thread1 extends Thread{
	private String name;
    public  TestThread(String name){
        this.name=name;
    }

    @Override
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(name);
        }
    }
}

实现Runnable接口

public class Thread2 implements Runnable{
	private String name;
    public  TestThread(String name){
        this.name=name;
    }

    @Override
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(name);
        }
    }
}

既然已经有了上面两种创建线程的方式,为什么还要有剩下两种呢?
Java现在的多线程机制,核心方法run是没有返回值的;如果要保存run方法里面的计算结果,必须等待run方法计算完,无论计算过程多么耗时。
那么就会想,能不能让子线程在计算的时候,让主线程异步执行呢?
这就要引出我们的Callable和FutureTask了

Callable&FutureTask

Callable

Callable是一个接口,源码如下:

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

call() 方法你可以将它看为run()方法,但是不同的一点是call()方法具有返回值。

如何通过Callable返回值

下面先看一个例子:

	public class FutureTaskDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<String> xianshiqi = new Callable<String>() {//购买显示器的线程
            @Override
            public String call() throws Exception {
                System.out.println("购买显示器");
                Thread.currentThread().sleep(1000);
                System.out.println("显示器到货");
                return "显示器购买成功";
            }
        };
        FutureTask<String> buytask = new FutureTask<String>(xianshiqi);
        new Thread(buytask).start();

        Callable<String> zhuji = new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("购买主机");
                Thread.currentThread().sleep(1000);
                System.out.println("主机到货");
                return "主机购买成功";
            }
        };
        FutureTask<String> buytask1 = new FutureTask<String>(zhuji);
        new Thread(buytask1).start();
        if (!buytask.isDone()){
            System.out.println("显示器未到货");
        }
        if (!buytask1.isDone()){
            System.out.println("主机未到货");
        }
        System.out.println(buytask1.get()+buytask.get());

    }
}

可以看出FutureTask接受了Callable对象,而Thread又接受了FutureTask对象(因为FutureTask实现了Runnable接口)

FutureTask

FutureTask实现了RunnableFuture接口:

	public class FutureTask<V> implements RunnableFuture<V> 

而RunnableFuture接口继承了Runnable和Future两个接口:

	public interface RunnableFuture<V> extends Runnable, Future<V> {
    /**
     * Sets this Future to the result of its computation
     * unless it has been cancelled.
     */
    void run();
}

上面的例子中,主要用到了FutureTask的两个方法:一个是isDone(),一个是get()。下面就两个方法看一下Java是如何实现的。

isDone()

	public boolean isDone() {
        return state != NEW;
    }

即该task状态不为new时返回true。

get()

	public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

意思是如果状态还没有完成,则等待,直到完成后返回report(s).

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值