1. 程式人生 > >Java併發之ThreadPoolExecutor和FutureTask

Java併發之ThreadPoolExecutor和FutureTask

ExecutorService.submit(Runnable task)方法及其過載方法的返回型別為Future,其真實型別為FutureTask。類圖如下:


由類圖可知,FutureTask是Future和Runnable的合體,並且持有任務Runnable或者Callable。future.get()是一個阻塞方法,直到任務完成才返回。再看ThreadPoolExecutor類圖:


當ExecutorService.submit(Runnable task)方法及其過載方法執行時(這些方法由AbstractExecutorService實現),FutureTask會被例項化:

public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Object> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
這些方法都呼叫了execute()方法。需要注意的是submit(Runnable task)方法返回的Future呼叫其get()將返回null。 newTaskFor()方法:
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }
FutureTask構造方法:
public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        sync = new Sync(callable);
    }

 public FutureTask(Runnable runnable, V result) {
        sync = new Sync(Executors.callable(runnable, result));
    }
callable和runnable都會被包裝成Sync。Executors.callable()方法:
public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }
再看看Executors的幾個建立執行緒池的靜態方法:
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
它們都例項化了一個執行緒池,並且傳入了相應的阻塞佇列。

相關推薦

Java併發ThreadPoolExecutorFutureTask

ExecutorService.submit(Runnable task)方法及其過載方法的返回型別為Future,其真實型別為FutureTask。類圖如下: 由類圖可知,FutureTask是Future和Runnable的合體,並且持有任務Runnable或者Cal

Java併發sleep() wait(n) 、 wait() 的區別

sleep() 和 wait(n) 、 wait() 的區別 答: sleep 方法:是 Thread 類的靜態方法,當前執行緒將睡眠 n 毫秒,執行緒進入阻塞狀態。當睡眠時間到了,會接觸阻塞,進入可

Java併發ThreadPoolExecutor原始碼解析(三)

Worker 先前,筆者講解到ThreadPoolExecutor.addWorker(Runnable firstTask, boolean core),在這個方法中工作執行緒可能建立成功,也可能建立失敗,具體視執行緒池的邊界條件,以及當前記憶體情況而定。 那麼,如果執行緒池當前的狀態,是允許建立Worke

java併發 CopyOnWriteArrayList的原理使用方法

描述 CopyOnWriteArrayList:CopyOnWriteArrayList這是一個ArrayList的執行緒安全的變體,其原理大概可以通俗的理解為:初始化的時候只有一個容器,很常一段時間,這個容器資料、數量等沒有發生變化的時候,大家(多個執行緒),都是讀取(假設這段時間裡只

java併發原子操作類(AtomicLong原始碼分析)非阻塞演算法

  背景 近年來,在併發演算法領域的大多數研究都側重於非阻塞演算法,這種演算法用底層的原子機器指令(例如比較併發交換指令)代替鎖來確保資料在併發訪問中的一致性。非阻塞演算法被廣泛的用於在作業系統和JVM中實現執行緒/程序排程機制、垃圾回收機制以及鎖和其他併發資料結構。 與基於鎖

Java多執行緒-併發sleep() wait(n) 、 wait() 的區別

sleep() 和 wait(n) 、 wait() 的區別 答: sleep 方法:是 Thread 類的靜態方法,當前執行緒將睡眠 n 毫秒,執行緒進入阻塞狀態。當睡眠時間到了,會接觸阻塞,進入可執行狀態,等待 CPU 的到來。睡眠不釋放鎖(如果有的話) wai

java併發----原子性,可見性有序性(轉載)

一、併發程式設計中的三個概念 在併發程式設計中,我們通常會遇到以下三個問題:原子性問題,可見性問題,有序性問題。我們先看具體看一下這三個概念: 1.原子性 原子性:即一個操作或者多個操作 要麼全部執行並且執行的過程不會被任何因素打斷,要麼就都不執行。 一個很經典的例子就是銀行

Java併發AQS用法原始碼分析

概念 AQS:佇列同步器AbstractQueuedSynchronizer(以下簡稱同步器),是用來構建鎖或者其他同步元件的基礎框架,許多同步器可以通過AQS很容易的並且高效的構建出來。不僅RenntrantLock和Semaphore是基於AQS構建的,還包括CountDownLat

Java併發訊號量、倒計數門閂、迴圈柵欄LockSupport

1、訊號量(Semaphore) 訊號量(Semaphore)是對鎖的擴充套件,內部鎖synchronized和重入鎖ReentrantLock一次都只允許一個執行緒訪問一個資源,而訊號量卻可以指定多個執行緒同時訪問某個資源。 // 指定準入數,即能同時

[滄海拾遺]java併發CountDownLatch、SemaphoreCyclicBarrier

JAVA併發包中有三個類用於同步一批執行緒的行為,分別是CountDownLatch、Semaphore和CyclicBarrier。 CountDownLatch CountDownLatch是一個計數器閉鎖,主要的功能就是通過await()方法來阻塞住當前執行緒,

Java併發synchronized關鍵字Lock介面

歡迎點贊閱讀,一同學習交流,有疑問請留言 。 GitHub上也有開源 JavaHouse,歡迎star 引用 當開發過程中,我們遇到併發問題。怎麼解決? 一種解決方式,簡單粗暴:上鎖。將千軍萬馬都給攔下來,只允許一個人過獨木橋。書面意思就是將並行的程式變成序列的程式。現實的鎖有門鎖、掛鎖和抽屜鎖等等。

java基礎getpost的差別

oge tracking data- 宋體 行處理 art 其它 family 我們 上篇博文講到HTTP協議,本篇介紹HTTP請求方法中get和post的差別: 首先,最明顯的一點表象上的差別:GET 方式。將請求參數附加在url之後,POST將請求參數附加在請求頭

Java SEbreakcontinue標簽

功能 static chang 感謝 .net author ack pac family 文是學習網絡上的文章時的總結,感謝大家無私的分享。 Java沒有提供goto功能,可是保留了gotokeyword。在java中能夠使用break標簽和continue標簽功能實

Java基礎finalstatic關鍵字

推薦 構造方法 其他 如果 靈活 位置 map 機制 lis 一、final 根據程序上下文環境,它可以修飾非抽象類、非抽象類成員方法和變量。 final類不能被繼承,沒有子類,final類中的方法默認是final的。 final

HBase概念學習(四)Java API掃描過濾器

影響 產生 str 實例 分享 get 批量 java api track HBase主要的CRUD操作就不多介紹了,無非就是Put,Get。Delete三個類的運用。 本文相當於是閱讀HBase權威指南的總結。 一、掃描(Scan) 如今看一下掃

Java基礎thissuper關鍵字用法

鏈接 tps 事件 歧義 調用 數據 沒有 方法名 訪問 this 在java中,this是一個引用當前類對象的引用變量,主要有以下幾種用法: 引用當前類的實例變量· this關鍵字可以用來引用當前類的實例變量。如果實例變量和某個方法的參數之間存在歧義(實例變量和參數命名相

Java 基礎 continue break

不執行 string In pre www ont ring str 如果 http://www.verejava.com/?id=17159306674727 public class Test2 { public static void main(String[

資料結構JAVA佇列

一、涉及的內容大綱 二、簡單介紹棧、佇列和其他資料結構的不同 1 對於其他的資料結構而言,都適用與資料庫應用中作資料記錄。但是因為棧和佇列的生命週期比那些資料庫型別的資料結構要短,所以他們只是在程式的操作期間才會建立和執行,在完成任務之後就會被銷燬。所以棧和佇列更多的是用於構思演算法的

26 Java學習NIOIO得比較

轉自:https://www.cnblogs.com/aspirant/p/8630283.html    一、概念      NIO即New IO(非阻塞IO),這個庫是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,

java 併發CountDownLatch

概述 CountDownLatch是一個用來控制併發的很常見的工具,它允許一個或者多個執行緒等待其他的執行緒執行到某一操作,比如說需要去解析一個excel的資料,為了更快的解析則每個sheet都使用一個執行緒去進行解析,但是最後的彙總資料的工作則需要等待每個sheet的解析工作完成之後才