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

Java concurrency線程池之Callable和Future_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

 更新時(shí)間:2017年06月15日 15:14:57   作者:skywang12345  
這篇文章主要為大家詳細(xì)介紹了Java concurrency線程池之Callable和Future,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Callable 和 Future 簡介

  Callable 和 Future 是比較有趣的一對組合。當(dāng)我們需要獲取線程的執(zhí)行結(jié)果時(shí),就需要用到它們。Callable用于產(chǎn)生結(jié)果,F(xiàn)uture用于獲取結(jié)果。

1. Callable

Callable 是一個(gè)接口,它只包含一個(gè)call()方法。Callable是一個(gè)返回結(jié)果并且可能拋出異常的任務(wù)。
為了便于理解,我們可以將Callable比作一個(gè)Runnable接口,而Callable的call()方法則類似于Runnable的run()方法。
Callable的源碼如下:

public interface Callable<V> {
 V call() throws Exception;
}

說明:從中我們可以看出Callable支持泛型。 

2. Future

Future 是一個(gè)接口。它用于表示異步計(jì)算的結(jié)果。提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并獲取計(jì)算的結(jié)果。
Future的源碼如下:

public interface Future<V> {
 // 試圖取消對此任務(wù)的執(zhí)行。
 boolean cancel(boolean mayInterruptIfRunning)

 // 如果在任務(wù)正常完成前將其取消,則返回 true。
 boolean isCancelled()

 // 如果任務(wù)已完成,則返回 true。
 boolean isDone()

 // 如有必要,等待計(jì)算完成,然后獲取其結(jié)果。
 V  get() throws InterruptedException, ExecutionException;

 // 如有必要,最多等待為使計(jì)算完成所給定的時(shí)間之后,獲取其結(jié)果(如果結(jié)果可用)。
 V  get(long timeout, TimeUnit unit)
  throws InterruptedException, ExecutionException, TimeoutException;
}

說明: Future用于表示異步計(jì)算的結(jié)果。它的實(shí)現(xiàn)類是FutureTask,在講解FutureTask之前,我們先看看Callable, Future, FutureTask它們之間的關(guān)系圖,如下:

說明:

(01) RunnableFuture是一個(gè)接口,它繼承了Runnable和Future這兩個(gè)接口。RunnableFuture的源碼如下:

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

(02) FutureTask實(shí)現(xiàn)了RunnableFuture接口。所以,我們也說它實(shí)現(xiàn)了Future接口。 

示例和源碼分析(基于JDK1.7.0_40)

我們先通過一個(gè)示例看看Callable和Future的基本用法,然后再分析示例的實(shí)現(xiàn)原理。

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

class MyCallable implements Callable {

 @Override 
 public Integer call() throws Exception {
 int sum = 0;
 // 執(zhí)行任務(wù)
 for (int i=0; i<100; i++)
  sum += i;
 //return sum; 
 return Integer.valueOf(sum);
 } 
}

public class CallableTest1 {

 public static void main(String[] args) 
 throws ExecutionException, InterruptedException{
 //創(chuàng)建一個(gè)線程池
 ExecutorService pool = Executors.newSingleThreadExecutor();
 //創(chuàng)建有返回值的任務(wù)
 Callable c1 = new MyCallable();
 //執(zhí)行任務(wù)并獲取Future對象 
 Future f1 = pool.submit(c1);
 // 輸出結(jié)果
 System.out.println(f1.get()); 
 //關(guān)閉線程池 
 pool.shutdown(); 
 }
}

運(yùn)行結(jié)果:

4950

結(jié)果說明:

  在主線程main中,通過newSingleThreadExecutor()新建一個(gè)線程池。接著創(chuàng)建Callable對象c1,然后再通過pool.submit(c1)將c1提交到線程池中進(jìn)行處理,并且將返回的結(jié)果保存到Future對象f1中。然后,我們通過f1.get()獲取Callable中保存的結(jié)果;最后通過pool.shutdown()關(guān)閉線程池。 

1. submit()

submit()在java/util/concurrent/AbstractExecutorService.java中實(shí)現(xiàn),它的源碼如下:

public <T> Future<T> submit(Callable<T> task) {
 if (task == null) throw new NullPointerException();
 // 創(chuàng)建一個(gè)RunnableFuture對象
 RunnableFuture<T> ftask = newTaskFor(task);
 // 執(zhí)行“任務(wù)ftask”
 execute(ftask);
 // 返回“ftask”
 return ftask;
}

說明:submit()通過newTaskFor(task)創(chuàng)建了RunnableFuture對象ftask。它的源碼如下:

protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
 return new FutureTask<T>(callable);
}
 

2. FutureTask的構(gòu)造函數(shù)

FutureTask的構(gòu)造函數(shù)如下:

public FutureTask(Callable<V> callable) {
 if (callable == null)
 throw new NullPointerException();
 // callable是一個(gè)Callable對象
 this.callable = callable;
 // state記錄FutureTask的狀態(tài)
 this.state = NEW; // ensure visibility of callable
}

3. FutureTask的run()方法

我們繼續(xù)回到submit()的源碼中。
在newTaskFor()新建一個(gè)ftask對象之后,會(huì)通過execute(ftask)執(zhí)行該任務(wù)。此時(shí)ftask被當(dāng)作一個(gè)Runnable對象進(jìn)行執(zhí)行,最終會(huì)調(diào)用到它的run()方法;ftask的run()方法在java/util/concurrent/FutureTask.java中實(shí)現(xiàn),源碼如下:

public void run() {
 if (state != NEW ||
 !UNSAFE.compareAndSwapObject(this, runnerOffset,
     null, Thread.currentThread()))
 return;
 try {
 // 將callable對象賦值給c。
 Callable<V> c = callable;
 if (c != null && state == NEW) {
  V result;
  boolean ran;
  try {
  // 執(zhí)行Callable的call()方法,并保存結(jié)果到result中。
  result = c.call();
  ran = true;
  } catch (Throwable ex) {
  result = null;
  ran = false;
  setException(ex);
  }
  // 如果運(yùn)行成功,則將result保存
  if (ran)
  set(result);
 }
 } finally {
 runner = null;
 // 設(shè)置“state狀態(tài)標(biāo)記”
 int s = state;
 if (s >= INTERRUPTING)
  handlePossibleCancellationInterrupt(s);
 }
}

說明:run()中會(huì)執(zhí)行Callable對象的call()方法,并且最終將結(jié)果保存到result中,并通過set(result)將result保存。
      之后調(diào)用FutureTask的get()方法,返回的就是通過set(result)保存的值。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中UUID生成原理及優(yōu)缺點(diǎn)

    Java中UUID生成原理及優(yōu)缺點(diǎn)

    本文將詳細(xì)講解UUID的生成原理、特性、實(shí)用場景以及優(yōu)缺點(diǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • JUnit測試控制@Test執(zhí)行順序的三種方式小結(jié)

    JUnit測試控制@Test執(zhí)行順序的三種方式小結(jié)

    這篇文章主要介紹了JUnit測試控制@Test執(zhí)行順序的三種方式小結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 詳解Java中異步轉(zhuǎn)同步的六種方法

    詳解Java中異步轉(zhuǎn)同步的六種方法

    針對應(yīng)用中異步調(diào)用,能不能像同步調(diào)用一樣立刻獲取到命令的執(zhí)行結(jié)果,如何實(shí)現(xiàn)異步轉(zhuǎn)同步?不要擔(dān)心,本文就來為大家詳細(xì)講講Java中異步轉(zhuǎn)同步的六種方法,感興趣的可以了解一下
    2022-06-06
  • springboot無法跳轉(zhuǎn)頁面的問題解決方案

    springboot無法跳轉(zhuǎn)頁面的問題解決方案

    這篇文章主要介紹了springboot無法跳轉(zhuǎn)頁面的問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • SpringBoot?AOP?@Pointcut切入點(diǎn)表達(dá)式排除某些類方式

    SpringBoot?AOP?@Pointcut切入點(diǎn)表達(dá)式排除某些類方式

    這篇文章主要介紹了SpringBoot?AOP?@Pointcut切入點(diǎn)表達(dá)式排除某些類方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 提升性能秘密武器Java Unsafe類面試精講

    提升性能秘密武器Java Unsafe類面試精講

    這篇文章主要為大家介紹了提升性能秘密武器Java Unsafe類面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Java Swing JToggleButton開關(guān)按鈕的實(shí)現(xiàn)

    Java Swing JToggleButton開關(guān)按鈕的實(shí)現(xiàn)

    這篇文章主要介紹了Java Swing JToggleButton開關(guān)按鈕的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • java開發(fā)工作中對InheritableThreadLocal使用思考

    java開發(fā)工作中對InheritableThreadLocal使用思考

    這篇文章主要為大家介紹了java開發(fā)工作中對InheritableThreadLocal使用思考詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 深入了解Java并發(fā)AQS的獨(dú)占鎖模式

    深入了解Java并發(fā)AQS的獨(dú)占鎖模式

    AQS是一種提供了原子式管理同步狀態(tài)、阻塞和喚醒線程功能以及隊(duì)列模型的簡單框架。一般來說,同步工具實(shí)現(xiàn)鎖的控制分為獨(dú)占鎖和共享鎖,而AQS提供了對這兩種模式的支持。本文主要來介紹一下獨(dú)占鎖模式,需要的可以參考一下
    2022-10-10
  • 面試官:Java中new Object()到底占用幾個(gè)字節(jié)

    面試官:Java中new Object()到底占用幾個(gè)字節(jié)

    這篇文章主要介紹了面試官:Java中new Object()到底占用幾個(gè)字節(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02

最新評論