欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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應(yīng)該是我們最熟悉的接口,它只有一個run()函數(shù),用于將耗時操作寫在其中, 該函數(shù)沒有返回值 。然后使用某個線程去執(zhí)行該runnable即可實(shí)現(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ù)返回的類型就是客戶程序傳遞進(jìn)來的V類型。

Future

Executor就是Runnable和Callable的調(diào)度容器,F(xiàn)uture就是對于具體的Runnable或者Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢是否完成、獲取結(jié)果、設(shè)置結(jié)果操作。get方法會阻塞,直到任務(wù)返回結(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實(shí)現(xiàn)了Runnbale又實(shí)現(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類型的任務(wù)。該適配函數(shù)的實(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實(shí)現(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>,即實(shí)現(xiàn)了Runnbale又實(shí)現(xiàn)了Futrue<V>這兩個接口, 
   * 另外它還可以包裝Runnable(實(shí)際上會轉(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>,即實(shí)現(xiàn)了Runnbale又實(shí)現(xiàn)了Futrue<V>這兩個接口, 
   * 另外它還可以包裝Runnable(實(shí)際上會轉(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)文章

  • MyBatis學(xué)習(xí)筆記(二)之關(guān)聯(lián)關(guān)系

    MyBatis學(xué)習(xí)筆記(二)之關(guān)聯(lián)關(guān)系

    這篇文章主要介紹了MyBatis學(xué)習(xí)筆記(二)之關(guān)聯(lián)關(guān)系 的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Java設(shè)計模式之適配器模式簡介

    Java設(shè)計模式之適配器模式簡介

    這篇文章主要介紹了Java設(shè)計模式之適配器模式,需要的朋友可以參考下
    2014-07-07
  • eclipse中maven的pom.xml文件中增加依賴的方法

    eclipse中maven的pom.xml文件中增加依賴的方法

    日 在Maven項目中,可以使用pom.xml文件來添加依賴包,本文主要介紹了eclipse中maven的pom.xml文件中增加依賴的方法,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Java實(shí)現(xiàn)記事本功能

    Java實(shí)現(xiàn)記事本功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)記事本功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 實(shí)戰(zhàn)講解Maven安裝及基本使用詳解

    實(shí)戰(zhàn)講解Maven安裝及基本使用詳解

    這篇文章主要介紹了實(shí)戰(zhàn)講解Maven安裝及基本使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Java線程之線程同步synchronized和volatile詳解

    Java線程之線程同步synchronized和volatile詳解

    這篇文章主要介紹了Java線程之線程同步synchronized和volatile詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • servlet創(chuàng)建web后端程序的示例代碼

    servlet創(chuàng)建web后端程序的示例代碼

    本文主要介紹了servlet創(chuàng)建web后端程序的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 數(shù)組在java中的擴(kuò)容的實(shí)例方法

    數(shù)組在java中的擴(kuò)容的實(shí)例方法

    在本篇文章里小編給大家分享的是一篇關(guān)于數(shù)組在java中的擴(kuò)容的實(shí)例方法內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-01-01
  • Hibernate悲觀鎖和樂觀鎖實(shí)例詳解

    Hibernate悲觀鎖和樂觀鎖實(shí)例詳解

    這篇文章主要介紹了Hibernate悲觀鎖和樂觀鎖實(shí)例詳解,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • Java語言打印九九乘法表

    Java語言打印九九乘法表

    這篇文章主要為大家詳細(xì)介紹了Java語言打印九九乘法表的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論