Java线程之Runnable,Callable,FutureTask

本文介绍了Java中的Runnable、Callable接口以及FutureTask的使用。Runnable用于无返回值的任务,而Callable可以返回结果。FutureTask是ExecutorService提交任务时的封装,提供了取消任务、获取结果、判断任务状态等方法。

一.Runnable, Callable, FutureTask简介

  • Runnable:我们需要实现run()方法,然后放入Thread中运行,无返回值。
  • Callable:实现T call()方法,由ExecutorService.submit()放入线程池中运行,具有返回值。
  • FutureTask:所有由ExecutorService.submit()放入线程池中的任务,不管是Runnable或者是Callable最后都封装成一个FutureTask,并且返回,我们可以通过返回的FutureTask对线程进行控制,比如获得结果,取消执行,判断是否执行完成。 

二.Runnable

        这个接口只有一个run方法,当我们想执行一个任务,最简单方法就是实现一个Runnable接口,将它放入Thread中执行就可以了。
例:
    
    static public void main(String args[]){
        runnableTest();
    }
	/**
     * 线程执行中
     */
    static public void runnableTest(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程执行中");
            }
        });
        thread.run();
    }
        这个就是一个很简单的线程执行示例,我们可以通过这个方法做些异步的操作。这样是有局限性的,如果我们需要查看执行结果,只能另外的写代码去查看执行的结果。

二.Callable

        Callable是一个可以执行有返回值的任务,这也是他和Runnable的区别
例:
    static public void useFutureTaskWithCallable(){
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        Future<?> future = executorService.submit(new Callable<String>() {

            @Override
            public String call() throws Exception {
                return "ttttt";
            }
        });
        try {
            showMessage(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
Callable不支持直接放入Thread中运行。它可以直接通过submit提交给线程池,最后运行,通过返回的Future.get()取得结果。那么Future是什么呢?


三.Future

Future是用于对线程控制的接口,当我们用线程池的Submit方法提交一个任务时候,就会返回一个可以对线程操控的Future对象。Future有方法呢?
  • boolean cancel(boolean mayInterruptIfRunning) 取消线程的执行mayInterruptIfRunning值为true时,这个线程会调用interrupt,线程可能会中断。为false时这个线程不会调用interrupt。
  • V get()调用方法的线程会阻塞直到任务执行完成,获得返回值
  • V get(long timeout, TimeUnit unit)设定获取结果线程最长阻塞时间,如果在这个时间呢还没有返回结果,会抛出一个TimeoutException异常
  • boolean isCancelled()判断线程是否被取消执行
  • boolean isDone()判断线程是否执行完成

二.FutureTask

FutureTask是Future的实现类,也就是说只有通过这个类我们才能对线程实现控制。所有放入线程池中的任务不管是Runnable,Callable都会被封装成一个FutureTask,FutureTask也提供了通过Runnable和Callable构造一个FutureTask的方法。
  • FutureTask(Runnable runnable, V result)
  • FutureTask(Callable<V> callable)

四.关于继承

FutureTask 实现的是RunnableFuture接口.
public class FutureTask<V> implements RunnableFuture<V>
RunnableFuture接口继承的是Runnable,Future接口
public interface RunnableFuture<V> extends Runnable, Future<V>
也就是说FutureTask具有run方法和线程控制的那些方法。那么Callable呢?
Callable没有继承任何的接口,它只有一个run方法
public interface Callable<V> {
    V call() throws Exception;
}
在FutureTask中,每个传入的Runnable都被封装成一个Callable对象,中间通过适配器模式RunnableAdapter,将不同的接口组装成一相同的call方法。
然后FutureTask的run方法中去调用自己的Callable对象。
好嘛。run变成call再变成run。变一次之后就具有返回值功能了。
值得一提,线程池的submit封装成的FutureTask,最后执行任务的时候就是调用Thread去执行的,也就是说执行的是run方法。

所以说所有的都是异端,除了Runnable。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值