1. 程式人生 > >Java之執行緒池原始碼深入理解

Java之執行緒池原始碼深入理解

在前面的文章中,我們使用執行緒的時候就去建立一個執行緒,這樣實現起來非常簡便,但是就會有一個問題:

如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,這樣頻繁建立執行緒就會大大降低系統的效率,因為頻繁建立執行緒和銷燬執行緒需要時間。

那麼有沒有一種辦法使得執行緒可以複用,就是執行完一個任務,並不被銷燬,而是可以繼續執行其他的任務?

在Java中可以通過執行緒池來達到這樣的效果。今天我們就來詳細講解一下Java的執行緒池,首先我們從最核心的ThreadPoolExecutor類中的方法講起,然後再講述它的實現原理,接著給出了它的使用示例,最後討論了一下如何合理配置執行緒池的大小。

以下是本文的目錄大綱:

一.Java中的ThreadPoolExecutor類

二.深入剖析執行緒池實現原理

三.使用示例

四.如何合理配置執行緒池的大小

若有不正之處請多多諒解,並歡迎批評指正。

一.Java中的ThreadPoolExecutor類

java.uitl.concurrent.ThreadPoolExecutor類是執行緒池中最核心的一個類,因此如果要透徹地瞭解Java中的執行緒池,必須先了解這個類。下面我們來看一下ThreadPoolExecutor類的具體實現原始碼。

在ThreadPoolExecutor類中提供了四個構造方法:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class ThreadPoolExecutor extends AbstractExecutorService {      .....      public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime,TimeUnit unit,              BlockingQueue<Runnable> workQueue);        public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime,TimeUnit unit,              BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);        public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime,TimeUnit unit,              BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);        public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime,TimeUnit unit,          BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);      ... }

從上面的程式碼可以得知,ThreadPoolExecutor繼承了AbstractExecutorService類,並提供了四個構造器,事實上,通過觀察每個構造器的原始碼具體實現,發現前面三個構造器都是呼叫的第四個構造器進行的初始化工作。

下面解釋下一下構造器中各個引數的含義:

  • corePoolSize:核心池的大小,這個引數跟後面講述的執行緒池的實現原理有非常大的關係。在建立了執行緒池後,預設情況下,執行緒池中並沒有任何執行緒,而是等待有任務到來才建立執行緒去執行任務,除非呼叫了prestartAllCoreThreads()或者prestartCoreThread()方法,從這2個方法的名字就可以看出,是預建立執行緒的意思,即在沒有任務到來之前就建立corePoolSize個執行緒或者一個執行緒。預設情況下,在建立了執行緒池後,執行緒池中的執行緒數為0,當有任務來之後,就會建立一個執行緒去執行任務,當執行緒池中的執行緒數目達到corePoolSize後,就會把到達的任務放到快取隊列當中;
  • maximumPoolSize:執行緒池最大執行緒數,這個引數也是一個非常重要的引數,它表示線上程池中最多能建立多少個執行緒;
  • keepAliveTime:表示執行緒沒有任務執行時最多保持多久時間會終止。預設情況下,只有當執行緒池中的執行緒數大於corePoolSize時,keepAliveTime才會起作用,直到執行緒池中的執行緒數不大於corePoolSize,即當執行緒池中的執行緒數大於corePoolSize時,如果一個執行緒空閒的時間達到keepAliveTime,則會終止,直到執行緒池中的執行緒數不超過corePoolSize。但是如果呼叫了allowCoreThreadTimeOut(boolean)方法,線上程池中的執行緒數不大於corePoolSize時,keepAliveTime引數也會起作用,直到執行緒池中的執行緒數為0;
  • unit:引數keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態屬性:
1 2 3 4 5 6 7 TimeUnit.DAYS;               //天 TimeUnit.HOURS;             //小時 TimeUnit.MINUTES;           //分鐘 TimeUnit.SECONDS;           //秒 TimeUnit.MILLISECONDS;      //毫秒 TimeUnit.MICROSECONDS;      //微妙 TimeUnit.NANOSECONDS;       //納秒
  • workQueue:一個阻塞佇列,用來儲存等待執行的任務,這個引數的選擇也很重要,會對執行緒池的執行過程產生重大影響,一般來說,這裡的阻塞佇列有以下幾種選擇:
1 2 3 ArrayBlockingQueue; LinkedBlockingQueue; SynchronousQueue;

ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和Synchronous。執行緒池的排隊策略與BlockingQueue有關。

  • threadFactory:執行緒工廠,主要用來建立執行緒;
  • handler:表示當拒絕處理任務時的策略,有以下四種取值:
1 2 3 4 ThreadPoolExecutor.AbortPolicy:丟棄任務並丟擲RejectedExecutionException異常。 ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不丟擲異常。 ThreadPoolExecutor.DiscardOldestPolicy:丟棄佇列最前面的任務,然後重新嘗試執行任務(重複此過程) ThreadPoolExecutor.CallerRunsPolicy:由呼叫執行緒處理該任務

具體引數的配置與執行緒池的關係將在下一節講述。

從上面給出的ThreadPoolExecutor類的程式碼可以知道,ThreadPoolExecutor繼承了AbstractExecutorService,我們來看一下AbstractExecutorService的實現:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

相關推薦

Java執行原始碼深入理解

在前面的文章中,我們使用執行緒的時候就去建立一個執行緒,這樣實現起來非常簡便,但是就會有一個問題: 如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,這樣頻繁建立執行緒就會大大降低系統的效率,因為頻繁建立執行緒和銷燬執行

java白開水 —— 執行的一點理解

目錄 1、前面 2、java執行緒池 3、c++執行緒池 4、區別 5、寫一個 6、使用 7、其它 內容 1、前面 執行緒池主要用於減少應用程式執行緒的數量並提供工作執行緒的管理。應用程式可以排隊工作項,將

java執行面試題

面試官:執行緒池有哪些?分別的作用是什麼? 常用的執行緒池有: newSingleThreadExecutor newFixedThreadExecutor newCacheThreadExecutor newScheduleThreadExecutor 1、newSingleTh

java執行簡單實現

以前做的東西,實現一個簡單的多執行緒機制,開始之前,現說說原理性的東西吧,下面是我在ibm開發者上搜到的內容 執行緒池的技術背景   在面向物件程式設計中,建立和銷燬物件是很費時間的,因為建立一個物件要獲取記憶體資源或者其它更多資源。在Java中更是如此,虛擬機器將

Java 執行

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolDem01 { public static void main(String[]

Tomcat執行深入理解

1.工作機制: Tomcat啟動時如果沒有請求過來,那麼執行緒數(都是指執行緒池的)為0; 一旦有請求,Tomcat會初始化minSapreThreads設定的執行緒數; 2.執行緒池作用: Tomcat的執行緒池的執行緒數跟你的瞬間併發有關係,比如maxThre

Java執行執行深入分析

執行緒池是併發包裡面很重要的一部分,在實際情況中也是使用很多的一個重要元件。 下圖描述的是執行緒池API的一部分。廣義上的完整執行緒池可能還包括Thread/Runnable、Timer/TimerTask等部分。這裡只介紹主要的和高階的API以及架構和原理。 大

Java併發包原始碼學習執行(一)ThreadPoolExecutor原始碼分析

Java中使用執行緒池技術一般都是使用Executors這個工廠類,它提供了非常簡單方法來建立各種型別的執行緒池: public static ExecutorService newFixedThreadPool(int nThreads) public static ExecutorService

java併發程式設計執行,執行,ansync執行原始碼解析

前言 java開源長了, 程式碼久了,網上對於執行緒那是眾說紛紜,一直縈繞我心頭的,jdk執行緒池好還是spring執行緒池好

死磕 java執行系列執行深入解析——體系結構

(手機橫屏看原始碼更方便) 注:java原始碼分析部分如無特殊說明均基於 java8 版本。 簡介 Java的執行緒池是塊硬骨頭,對執行緒池的原始碼做深入研究不僅能提高對Java整個併發程式設計的理解,也能提高自己在面試中的表現,增加被錄取的可能性。 本系列將分成很多個章節,本章作為執行緒池的第一章將對

死磕 java執行系列執行深入解析——生命週期

(手機橫屏看原始碼更方便) 注:java原始碼分析部分如無特殊說明均基於 java8 版本。 注:執行緒池原始碼部分如無特殊說明均指ThreadPoolExecutor類。 簡介 上一章我們一起重溫了下執行緒的生命週期(六種狀態還記得不?),但是你知不知道其實執行緒池也是有生命週期的呢?! 問題 (1)

死磕 java執行系列執行深入解析——普通任務執行流程

(手機橫屏看原始碼更方便) 注:java原始碼分析部分如無特殊說明均基於 java8 版本。 注:執行緒池原始碼部分如無特殊說明均指ThreadPoolExecutor類。 簡介 前面我們一起學習了Java中執行緒池的體系結構、構造方法和生命週期,本章我們一起來學習執行緒池中普通任務到底是怎麼執行的。

死磕 java執行系列執行深入解析——未來任務執行流程

(手機橫屏看原始碼更方便) 注:java原始碼分析部分如無特殊說明均基於 java8 版本。 注:執行緒池原始碼部分如無特殊說明均指ThreadPoolExecutor類。 簡介 前面我們一起學習了執行緒池中普通任務的執行流程,但其實執行緒池中還有一種任務,叫作未來任務(future task),使用它

死磕 java執行系列執行深入解析——定時任務執行流程

(手機橫屏看原始碼更方便) 注:java原始碼分析部分如無特殊說明均基於 java8 版本。 注:本文基於ScheduledThreadPoolExecutor定時執行緒池類。 簡介 前面我們一起學習了普通任務、未來任務的執行流程,今天我們再來學習一種新的任務——定時任務。 定時任務是我們經常會用到的一

Java併發程式設計執行(三)

一.介紹 Java通過Executors提供四種執行緒池,分別為: (1)newCachedThreadPool:建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒。 (2)newFixedThreadPool: 建立一個定長執行緒池,可控制

Java執行-併發執行

執行緒池有了解嗎? 答: java.util.concurrent.ThreadPoolExecutor 類就是一個執行緒池。客戶端呼叫ThreadPoolExecutor.submit(Runnable task) 提交任務,執行緒池內部維護的工作者執行緒的數量就是該執行緒池的執行

Java基礎執行

一、執行緒池概念 執行緒池:其實就是一個容納多個執行緒的容器,其中的執行緒可以反覆使用,省去了頻繁建立執行緒物件的操作,無需反覆建立執行緒而消耗過多資源。 二、工作原理 三、合理利用執行緒池的好處 降低資源消耗。減少了建立和銷燬執行緒的次數,每個工作執行緒都可以

Java基礎學習——多執行執行

1.執行緒池介紹     執行緒池是一種執行緒使用模式。執行緒由於具有空閒(eg:等待返回值)和繁忙這種不同狀態,當數量過多時其建立、銷燬、排程等都會帶來開銷。執行緒池維護了多個執行緒,當分配可併發執行的任務時,它負責排程執行緒執行工作,執行完畢後執行緒不關閉而是返回執行緒池,

Java執行系列--“JUC執行”01 執行架構

概要 前面分別介紹了”Java多執行緒基礎”、”JUC原子類”和”JUC鎖”。本章介紹JUC的最後一部分的內容——執行緒池。內容包括: 執行緒池架構圖 執行緒池示例 執行緒池架構圖 執行緒池的架構圖如下: 1、Executor

Java執行系列--“JUC執行”05 執行原理(四)

概要 本章介紹執行緒池的拒絕策略。內容包括: 拒絕策略介紹 拒絕策略對比和示例 拒絕策略介紹 執行緒池的拒絕策略,是指當任務新增到執行緒池中被拒絕,而採取的處理措施。 當任務新增到執行緒池中之所以被拒絕,可能是由於:第一,執行緒池異常關閉。第二,任務數量