java多线程实现方式(三)

    伙伴们,又见面了,我们接着聊java多线程实现方式,上篇我们介绍了可以通过实现Runnable接口来实现多线程,但是会发现实现Runnable接口的方式执行run方法之后没有返回值,如果我们想获取执行之后的返回值呢,那么我们可以通过今天介绍的实现Callable接口的方法。首先看下Callable接口的源码:

@FunctionalInterface
public interface Callable<V> {
    /**
     * V为返回值类型 
     */
    V call() throws Exception;
}

通过@FunctionalInterface可以看出它是一个函数式接口,接收一个泛型作为返回值类型。对比下Runnable接口的源码:

@FunctionalInterface
public interface Runnable {
    //没有返回值 
    public abstract void run();
}

可以发现Callable接口中call方法不仅可以有返回值还可以抛出异常,而Runnable接口中run方法没有返回值并且不能往外抛出异常。举个Callable接口的栗子:

/**
 * 实现Callable接口
 */
public class CallableTest implements Callable<String> {
    @Override
    public String call() throws Exception {
        //返回线程名
        return Thread.currentThread().getName();
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CallableTest callableTest = new CallableTest();
        FutureTask<String> futureTask = new FutureTask(callableTest);
        new Thread(futureTask,"callTest").start();
        System.out.println(futureTask.get());
    }
}

栗子中我们传递了String类型作为call方法的返回值,接下来我们看看main方法中的写法。

首先看下FutureTask的源码:

public class FutureTask<V> implements RunnableFuture<V>{
//其中一个构造方法
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;      
    }
......
}

从中我们可以通过实现Callable接口的对象来创建FutureTask对象,FutureTask<V> 实现了 RunnableFuture<V>接口,接着分析下 RunnableFuture接口:

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

可见它继承了Runnable和Future<V>两个接口,那么就相当于FutureTask<V> 间接实现了Runnable接口。最后看下Thread的构造方法:

//可以给线程设置名称的构造方法
public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }
 public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

总结一下:在Thread类中有Runnable接口类型参数的构造方法,在上面的栗子中FutureTask<String>实现了 RunnableFuture<V> 接口,而 RunnableFuture<V> 接口又继承了Runnable接口和 Funture<V>接口,因此咱们可以将futureTask 当做是一个Runnable接口的实例(间接实现)传入Thread构造方法来创建并启动我们新建的线程,可以发现最终都是通过Thread对象调用start方法来获取CPU时间片从而执行线程,伙伴们 是这样不 咱们下期见!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值