栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的Runnable,Callable,Future,FutureTask的比较

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的Runnable,Callable,Future,FutureTask的比较

Java中的Runnable,Callable,Future,FutureTask的比较

Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。

Runnable

其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中, 该函数没有返回值 。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。Runnable的声明如下 :

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

Callable

Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是 call()函数有返回值 ,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :

@FunctionalInterface
public interface Callable {
  
  V call() throws Exception;
}

可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型。

Future

Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。Future声明如下:

* @see FutureTask
 * @see Executor
 * @since 1.5
 * @author Doug Lea
 * @param  The result type returned by this Future's {@code get} method
 */
public interface Future {

  
  boolean cancel(boolean mayInterruptIfRunning);

  
  boolean isCancelled();

  
  boolean isDone();

  
  V get() throws InterruptedException, ExecutionException;

  
  V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException;
}

FutureTask

FutureTask则是一个RunnableFuture< V>,而RunnableFuture实现了Runnbale又实现了Futrue< V>这两个接口:

public class FutureTask implements RunnableFuture {
......
}

RunnableFuture



public interface RunnableFuture extends Runnable, Future {
  
  void run();
}

另外FutureTask还可以包装Runnable和Callable< V>, 由构造函数注入依赖。


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

  
  public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;    // ensure visibility of callable
  }

可以看到,Runnable注入会被Executors.callable()函数转换为Callable类型,即FutureTask最终都是执行Callable类型的任务。该适配函数的实现如下 :


  public static  Callable callable(Runnable task, T result) {
    if (task == null)
      throw new NullPointerException();
    return new RunnableAdapter(task, result);
  }

RunnableAdapter适配器


  static final class RunnableAdapter implements Callable {
    final Runnable task;
    final T result;
    RunnableAdapter(Runnable task, T result) {
      this.task = task;
      this.result = result;
    }
    public T call() {
      task.run();
      return result;
    }
  }

由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行。并且还可以直接通过get()函数获取执行结果,该函数会阻塞,直到结果返回。

因此FutureTask既是Future、Runnable,又是包装了Callable(如果是Runnable最终也会被转换为Callable ), 它是这两者的合体。

完整示例:

package com.stay4it.rx;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class FutureTest {

  public static class Task implements Runnable {

    @Override
    public void run() {
      // TODO Auto-generated method stub
      System.out.println("run");
    }

  }
  public static class Task2 implements Callable {

    @Override
    public Integer call() throws Exception {
      System.out.println("call");
      return fibc(30);
    }

  }

    
  public static void testRunnable(){
    ExecutorService executorService = Executors.newCachedThreadPool();

    Future future = (Future) executorService.submit(new Task());
    try {
      System.out.println(future.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    executorService.shutdown();
  }

   
  public static void testCallable(){
    ExecutorService executorService = Executors.newCachedThreadPool();

    Future future = (Future) executorService.submit(new Task2());
    try {
      System.out.println(future.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    executorService.shutdown();
  }

    
  public static void testFutureTask(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    FutureTask futureTask = new FutureTask(new Task2());

    executorService.submit(futureTask);
    try {
      System.out.println(futureTask.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    executorService.shutdown();
  }

    
  public static void testFutureTask2(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    FutureTask futureTask = new FutureTask(new Runnable() {

      @Override
      public void run() {
 // TODO Auto-generated method stub
 System.out.println("testFutureTask2 run");
      }
    },fibc(30));

    executorService.submit(futureTask);
    try {
      System.out.println(futureTask.get());
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    executorService.shutdown();
  }



  public static void main(String[] args) {

    testCallable();

  }

   
  static int fibc(int num) { 
    if (num == 0) { 
      return 0; 
    } 
    if (num == 1) { 
      return 1; 
    } 
    return fibc(num - 1) + fibc(num - 2); 
  } 

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/147621.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号