一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java concurrency線程池之Callable和Future_動力節點Java學院整理

Java concurrency線程池之Callable和Future_動力節點Java學院整理

2020-11-18 10:48動力節點 Java教程

這篇文章主要為大家詳細介紹了Java concurrency線程池之Callable和Future,具有一定的參考價值,感興趣的小伙伴們可以參考一下

CallableFuture 簡介

  Callable 和 Future 是比較有趣的一對組合。當我們需要獲取線程的執行結果時,就需要用到它們。Callable用于產生結果,Future用于獲取結果。

1. Callable

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

?
1
2
3
public interface Callable<V> {
 V call() throws Exception;
}

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

2. Future

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface Future<V> {
 // 試圖取消對此任務的執行。
 boolean cancel(boolean mayInterruptIfRunning)
 
 // 如果在任務正常完成前將其取消,則返回 true。
 boolean isCancelled()
 
 // 如果任務已完成,則返回 true。
 boolean isDone()
 
 // 如有必要,等待計算完成,然后獲取其結果。
 V  get() throws InterruptedException, ExecutionException;
 
 // 如有必要,最多等待為使計算完成所給定的時間之后,獲取其結果(如果結果可用)。
 V  get(long timeout, TimeUnit unit)
  throws InterruptedException, ExecutionException, TimeoutException;
}

說明: Future用于表示異步計算的結果。它的實現類是FutureTask,在講解FutureTask之前,我們先看看Callable, Future, FutureTask它們之間的關系圖,如下:

Java concurrency線程池之Callable和Future_動力節點Java學院整理

說明:

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

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

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

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

我們先通過一個示例看看Callable和Future的基本用法,然后再分析示例的實現原理。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
 // 執行任務
 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{
 //創建一個線程池
 ExecutorService pool = Executors.newSingleThreadExecutor();
 //創建有返回值的任務
 Callable c1 = new MyCallable();
 //執行任務并獲取Future對象
 Future f1 = pool.submit(c1);
 // 輸出結果
 System.out.println(f1.get());
 //關閉線程池
 pool.shutdown();
 }
}

運行結果:

4950

結果說明:

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

1. submit()

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

?
1
2
3
4
5
6
7
8
9
public <T> Future<T> submit(Callable<T> task) {
 if (task == null) throw new NullPointerException();
 // 創建一個RunnableFuture對象
 RunnableFuture<T> ftask = newTaskFor(task);
 // 執行“任務ftask”
 execute(ftask);
 // 返回“ftask”
 return ftask;
}

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

?
1
2
3
4
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
 return new FutureTask<T>(callable);
}

2. FutureTask的構造函數

FutureTask的構造函數如下:

?
1
2
3
4
5
6
7
8
public FutureTask(Callable<V> callable) {
 if (callable == null)
 throw new NullPointerException();
 // callable是一個Callable對象
 this.callable = callable;
 // state記錄FutureTask的狀態
 this.state = NEW; // ensure visibility of callable
}

3. FutureTask的run()方法

我們繼續回到submit()的源碼中。
在newTaskFor()新建一個ftask對象之后,會通過execute(ftask)執行該任務。此時ftask被當作一個Runnable對象進行執行,最終會調用到它的run()方法;ftask的run()方法在java/util/concurrent/FutureTask.java中實現,源碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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 {
  // 執行Callable的call()方法,并保存結果到result中。
  result = c.call();
  ran = true;
  } catch (Throwable ex) {
  result = null;
  ran = false;
  setException(ex);
  }
  // 如果運行成功,則將result保存
  if (ran)
  set(result);
 }
 } finally {
 runner = null;
 // 設置“state狀態標記”
 int s = state;
 if (s >= INTERRUPTING)
  handlePossibleCancellationInterrupt(s);
 }
}

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 1769亚洲资源站365在线 | 91在线免费播放 | 色香婷婷 | 四虎成人免费大片在线 | 国产亚洲一欧美一区二区三区 | 成人深夜视频 | 暖暖在线日本 | 久久精品国产久精国产果冻传媒 | 福利一区在线观看 | 免费一级欧美片片线观看 | 色综合天天综合网国产人 | 国产在视频 | 亚州vs欧州vs日 | 2020精品极品国产色在线观看 | 91在线老师啪国自产 | 第一次破学生处破 | 国产福利一区二区精品视频 | 欧美办公室激情videos高清 | 高清色黄毛片一级毛片 | 人人最怕九月羊 | 网www天堂资源在线 王淑兰与铁柱全文免费阅读 | 精品视频久久久久 | 色综合色综合 | 9999视频| 99爱在线精品视频免费观看9 | 色在线看 | 羲义嫁密着中出交尾gvg794 | 日本视频中文字幕 | 4hu影院永久在线播放 | 国产精品视频1区 | 久久精品国产视频澳门 | re99热| 欧美z0z0人禽交 | 91精品天美精东蜜桃传媒免费 | 99国产情在线视频 | 99久久精品久久久久久清纯 | 亚洲a视频在线 | 亚洲精品123区在线观看 | 欧美一级乱妇老太婆特黄 | 99精彩视频在线观看 | 免费国产好深啊好涨好硬视频 |