最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的Runnable,Callable,F(xiàn)uture,F(xiàn)utureTask的比較

 更新時間:2017年02月20日 15:03:50   投稿:lqh  
這篇文章主要介紹了Java中的Runnable,Callable,F(xiàn)uture,F(xiàn)utureTask的比較的相關(guān)資料,需要的朋友可以參考下

Java中的Runnable,Callable,F(xiàn)uture,F(xiàn)utureTask的比較

Java中存在Runnable、Callable、Future、FutureTask這幾個與線程相關(guān)的類或者接口,在Java中也是比較重要的幾個概念,我們通過下面的簡單示例來了解一下它們的作用于區(qū)別。

Runnable

其中Runnable應該是我們最熟悉的接口,它只有一個run()函數(shù),用于將耗時操作寫在其中, 該函數(shù)沒有返回值 。然后使用某個線程去執(zhí)行該runnable即可實現(xiàn)多線程,Thread類在調(diào)用start()函數(shù)后就是執(zhí)行的是Runnable的run()函數(shù)。Runnable的聲明如下 :

@FunctionalInterface
public interface Runnable {
  /**
   * When an object implementing interface <code>Runnable</code> is used
   * to create a thread, starting the thread causes the object's
   * <code>run</code> method to be called in that separately executing
   * thread.
   * <p>
   * The general contract of the method <code>run</code> is that it may
   * take any action whatsoever.
   *
   * @see   java.lang.Thread#run()
   */
  public abstract void run();
}

Callable

Callable與Runnable的功能大致相似,Callable中有一個call()函數(shù),但是 call()函數(shù)有返回值 ,而Runnable的run()函數(shù)不能將結(jié)果返回給客戶程序。Callable的聲明如下 :

@FunctionalInterface
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()函數(shù)返回的類型就是客戶程序傳遞進來的V類型。

Future

Executor就是Runnable和Callable的調(diào)度容器,F(xiàn)uture就是對于具體的Runnable或者Callable任務的執(zhí)行結(jié)果進行取消、查詢是否完成、獲取結(jié)果、設置結(jié)果操作。get方法會阻塞,直到任務返回結(jié)果(Future簡介)。Future聲明如下:

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

  /**
   * Attempts to cancel execution of this task. This attempt will
   * fail if the task has already completed, has already been cancelled,
   * or could not be cancelled for some other reason. If successful,
   * and this task has not started when {@code cancel} is called,
   * this task should never run. If the task has already started,
   * then the {@code mayInterruptIfRunning} parameter determines
   * whether the thread executing this task should be interrupted in
   * an attempt to stop the task.
   *
   * <p>After this method returns, subsequent calls to {@link #isDone} will
   * always return {@code true}. Subsequent calls to {@link #isCancelled}
   * will always return {@code true} if this method returned {@code true}.
   *
   * @param mayInterruptIfRunning {@code true} if the thread executing this
   * task should be interrupted; otherwise, in-progress tasks are allowed
   * to complete
   * @return {@code false} if the task could not be cancelled,
   * typically because it has already completed normally;
   * {@code true} otherwise
   */
  boolean cancel(boolean mayInterruptIfRunning);

  /**
   * Returns {@code true} if this task was cancelled before it completed
   * normally.
   *
   * @return {@code true} if this task was cancelled before it completed
   */
  boolean isCancelled();

  /**
   * Returns {@code true} if this task completed.
   *
   * Completion may be due to normal termination, an exception, or
   * cancellation -- in all of these cases, this method will return
   * {@code true}.
   *
   * @return {@code true} if this task completed
   */
  boolean isDone();

  /**
   * Waits if necessary for the computation to complete, and then
   * retrieves its result.
   *
   * @return the computed result
   * @throws CancellationException if the computation was cancelled
   * @throws ExecutionException if the computation threw an
   * exception
   * @throws InterruptedException if the current thread was interrupted
   * while waiting
   */
  V get() throws InterruptedException, ExecutionException;

  /**
   * Waits if necessary for at most the given time for the computation
   * to complete, and then retrieves its result, if available.
   *
   * @param timeout the maximum time to wait
   * @param unit the time unit of the timeout argument
   * @return the computed result
   * @throws CancellationException if the computation was cancelled
   * @throws ExecutionException if the computation threw an
   * exception
   * @throws InterruptedException if the current thread was interrupted
   * while waiting
   * @throws TimeoutException if the wait timed out
   */
  V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException;
}

FutureTask

FutureTask則是一個RunnableFuture< V>,而RunnableFuture實現(xiàn)了Runnbale又實現(xiàn)了Futrue< V>這兩個接口:

public class FutureTask<V> implements RunnableFuture<V> {
......
}

RunnableFuture


/**
 * A {@link Future} that is {@link Runnable}. Successful execution of
 * the {@code run} method causes completion of the {@code Future}
 * and allows access to its results.
 * @see FutureTask
 * @see Executor
 * @since 1.6
 * @author Doug Lea
 * @param <V> The result type returned by this Future's {@code get} method
 */
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還可以包裝Runnable和Callable< V>, 由構(gòu)造函數(shù)注入依賴。

/**
   * Creates a {@code FutureTask} that will, upon running, execute the
   * given {@code Callable}.
   *
   * @param callable the callable task
   * @throws NullPointerException if the callable is null
   */
  public FutureTask(Callable<V> callable) {
    if (callable == null)
      throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;    // ensure visibility of callable
  }

  /**
   * Creates a {@code FutureTask} that will, upon running, execute the
   * given {@code Runnable}, and arrange that {@code get} will return the
   * given result on successful completion.
   *
   * @param runnable the runnable task
   * @param result the result to return on successful completion. If
   * you don't need a particular result, consider using
   * constructions of the form:
   * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
   * @throws NullPointerException if the runnable is null
   */
  public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;    // ensure visibility of callable
  }

可以看到,Runnable注入會被Executors.callable()函數(shù)轉(zhuǎn)換為Callable類型,即FutureTask最終都是執(zhí)行Callable類型的任務。該適配函數(shù)的實現(xiàn)如下 :

/**
   * Returns a {@link Callable} object that, when
   * called, runs the given task and returns the given result. This
   * can be useful when applying methods requiring a
   * {@code Callable} to an otherwise resultless action.
   * @param task the task to run
   * @param result the result to return
   * @param <T> the type of the result
   * @return a callable object
   * @throws NullPointerException if task null
   */
  public static <T> Callable<T> callable(Runnable task, T result) {
    if (task == null)
      throw new NullPointerException();
    return new RunnableAdapter<T>(task, result);
  }

RunnableAdapter適配器

/**
   * A callable that runs given task and returns given result
   */
  static final class RunnableAdapter<T> implements Callable<T> {
    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實現(xiàn)了Runnable,因此它既可以通過Thread包裝來直接執(zhí)行,也可以提交給ExecuteService來執(zhí)行。并且還可以直接通過get()函數(shù)獲取執(zhí)行結(jié)果,該函數(shù)會阻塞,直到結(jié)果返回。

因此FutureTask既是Future、Runnable,又是包裝了Callable(如果是Runnable最終也會被轉(zhuǎn)換為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<Integer> {

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

  }

   /** 
   * runnable, 無返回值 
   */ 
  public static void testRunnable(){
    ExecutorService executorService = Executors.newCachedThreadPool();

    Future<String> future = (Future<String>) 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();
  }

  /** 
   * Callable, 有返回值 
   */ 
  public static void testCallable(){
    ExecutorService executorService = Executors.newCachedThreadPool();

    Future<Integer> future = (Future<Integer>) 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();
  }

   /** 
   * FutureTask則是一個RunnableFuture<V>,即實現(xiàn)了Runnbale又實現(xiàn)了Futrue<V>這兩個接口, 
   * 另外它還可以包裝Runnable(實際上會轉(zhuǎn)換為Callable)和Callable 
   * <V>,所以一般來講是一個符合體了,它可以通過Thread包裝來直接執(zhí)行,也可以提交給ExecuteService來執(zhí)行 
   * ,并且還可以通過v get()返回執(zhí)行結(jié)果,在線程體沒有執(zhí)行完成的時候,主線程一直阻塞等待,執(zhí)行完則直接返回結(jié)果。 
   */ 
  public static void testFutureTask(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(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();
  }

   /** 
   * FutureTask則是一個RunnableFuture<V>,即實現(xiàn)了Runnbale又實現(xiàn)了Futrue<V>這兩個接口, 
   * 另外它還可以包裝Runnable(實際上會轉(zhuǎn)換為Callable)和Callable 
   * <V>,所以一般來講是一個符合體了,它可以通過Thread包裝來直接執(zhí)行,也可以提交給ExecuteService來執(zhí)行 
   * ,并且還可以通過v get()返回執(zhí)行結(jié)果,在線程體沒有執(zhí)行完成的時候,主線程一直阻塞等待,執(zhí)行完則直接返回結(jié)果。 
   */ 
  public static void testFutureTask2(){
    ExecutorService executorService = Executors.newCachedThreadPool();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(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();

  }

  /** 
   * 效率低下的斐波那契數(shù)列, 耗時的操作 
   * 
   * @param num 
   * @return 
   */ 
  static int fibc(int num) { 
    if (num == 0) { 
      return 0; 
    } 
    if (num == 1) { 
      return 1; 
    } 
    return fibc(num - 1) + fibc(num - 2); 
  } 

}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • springmvc的文件保存方法詳解

    springmvc的文件保存方法詳解

    這篇文章主要介紹了springmvc的文件保存方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • java同一個類中,一個無事務方法調(diào)用一個有事務方法時,事務失效問題

    java同一個類中,一個無事務方法調(diào)用一個有事務方法時,事務失效問題

    本文詳細介紹了Spring框架中事務管理的實現(xiàn)原理,包括@Transactional注解的使用、事務的開啟、提交和回滾機制,以及代理對象的兩種實現(xiàn)方式(JDK動態(tài)代理和CGLIB代理),文章還探討了在同一個類中調(diào)用有事務方法時事務失效的原因,并提供了解決方法
    2024-12-12
  • Java實現(xiàn)控制臺輸出兩點間距離

    Java實現(xiàn)控制臺輸出兩點間距離

    這篇文章主要介紹了Java實現(xiàn)控制臺輸出兩點間距離,涉及了部分編程坐標的問題,具有一定參考價值,需要的朋友可以了解下
    2017-09-09
  • Aop動態(tài)代理和cglib實現(xiàn)代碼詳解

    Aop動態(tài)代理和cglib實現(xiàn)代碼詳解

    這篇文章主要介紹了Aop動態(tài)代理和cglib實現(xiàn)代碼詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • struts2實現(xiàn)多文件上傳的示例代碼

    struts2實現(xiàn)多文件上傳的示例代碼

    本篇文章主要介紹了struts2實現(xiàn)多文件上傳的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 使用log4j2自定義配置文件位置和文件名(附log4j2.xml配置實例)

    使用log4j2自定義配置文件位置和文件名(附log4j2.xml配置實例)

    這篇文章主要介紹了使用log4j2自定義配置文件位置和文件名(附log4j2.xml配置實例),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java的線程池框架及線程池的原理

    java的線程池框架及線程池的原理

    這篇文章主要介紹了java的線程池框架及線程池的原理的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • JAVA實現(xiàn)微信APPV3支付保姆級教程

    JAVA實現(xiàn)微信APPV3支付保姆級教程

    微信實現(xiàn)支付功能與支付寶實現(xiàn)支付功能是相似的,這篇文章主要介紹了JAVA實現(xiàn)微信APPV3支付的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • MyBatis中如何查詢某個時間段內(nèi)的數(shù)據(jù)

    MyBatis中如何查詢某個時間段內(nèi)的數(shù)據(jù)

    這篇文章主要介紹了MyBatis中如何查詢某個時間段內(nèi)的數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Spring Cloud Hystrix線程池不足的解決方法

    Spring Cloud Hystrix線程池不足的解決方法

    這篇文章主要介紹了Spring Cloud Hystrix線程池不足的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02

最新評論

屏东县| 扎鲁特旗| 汝城县| 海口市| 霍林郭勒市| 平顶山市| 六安市| 绥芬河市| 东乌珠穆沁旗| 平利县| 盐亭县| 白城市| 广平县| 旺苍县| 上饶县| 建平县| 武安市| 华蓥市| 荥阳市| 兴国县| 革吉县| 石城县| 北碚区| 二连浩特市| 崇信县| 铁力市| 泌阳县| 扶风县| 东乡| 明溪县| 资阳市| 云林县| 老河口市| 加查县| 同仁县| 临漳县| 曲阳县| 泰兴市| 抚松县| 肇源县| 宁城县|