「漲知識」一篇文章讓你瞭解Java核心線程池

本篇文章通讀時間大概3分鐘,希望在三分鐘內的講解,對你有所幫助,一定要認真看並思考,好了。廢話不多數,直接上乾貨,本節內容我們講的是Java的線程池,在講之前我們首先看一下有哪些線程池,這些線程池我們不過多講解,因為我們的關注點是他們是如何實現的,和其運行的原理。


目錄

  1. 常用線程池列表
  2. ThreadPoolExecutor
  3. ThreadFactory線程工廠
  4. RejectedExecutionHandler拒絕策略
  5. Queue任務隊列

一. 常用線程池列表

這部分內容,只是幫助你回顧一下線程池的知識,大家重點看方法內的實現

1、構造一個固定線程數目的線程池,配置的corePoolSize與maximumPoolSize大小相同,同時使用了一個無界LinkedBlockingQueue存放阻塞任務,因此多餘的任務將存在再阻塞隊列,不會由RejectedExecutionHandler處理

「漲知識」一篇文章讓你瞭解Java核心線程池

2、構造一個緩衝功能的線程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一個無容量的阻塞隊列 SynchronousQueue,因此任務提交之後,將會創建新的線程執行;線程空閒超過60s將會銷燬

「漲知識」一篇文章讓你瞭解Java核心線程池

3、構造一個只支持一個線程的線程池,配置corePoolSize=maximumPoolSize=1,無界阻塞隊列LinkedBlockingQueue;保證任務由一個線程串行執行

「漲知識」一篇文章讓你瞭解Java核心線程池

4、構造有定時功能的線程池,配置corePoolSize,無界延遲阻塞隊列DelayedWorkQueue;有意思的是:maximumPoolSize=Integer.MAX_VALUE,由於DelayedWorkQueue是無界隊列,所以這個值是沒有意義的

「漲知識」一篇文章讓你瞭解Java核心線程池

的內容,知識幫助你回顧一下

二. ThreadPoolExecutor

相信大家從上面的眾多線程池中都已經看到了這個類,因為上面的線程池底層的構造都是由這個類創建的,

那麼我們就開始研究這個類

「漲知識」一篇文章讓你瞭解Java核心線程池

首先看一下構造方法,關於註釋一定要好好看,每個參數都理解了,那麼你就弄懂了

「漲知識」一篇文章讓你瞭解Java核心線程池

1. 核心的線程池

2. 最大線程池就是說你定義的線程池運行創建的最大線程數量

3. 空閒時間回收,當這個時間後還沒有任務執行就將線程回收

4. 單位,控制上面時間的單位,可以為秒,或者分鐘

5. 核心線程都已經去執行任務但是,任務還有,那麼久先放到這個隊列裡,就相當於集合

6. 創建線程用戶的線程工廠,裡面只有一個方法就是newThread,你可以自定義線程名

7. 拒絕策略,當任務已經執行不了,你拒絕的策略

「漲知識」一篇文章讓你瞭解Java核心線程池


三. ThreadFactory

ThreadFactory有什麼用呢? 其實就是一個接口,既然是線程工廠,那麼肯定就是創建線程的了

「漲知識」一篇文章讓你瞭解Java核心線程池

給當前線程分配名字和線程組方便控制。讀到這裡,有沒有一點啟發呢?

「漲知識」一篇文章讓你瞭解Java核心線程池

四. 拒絕策略

拒絕策略就是任務實在是已經執行不了,那麼就需要你告訴程序,怎麼樣去拒絕在執行其他任務

ThreadPoolExecutor類裡面是內置了4中拒絕策略,我們一個一個來分析

  • 策略-1

用於被拒絕任務的處理程序,它直接在 execute 方法的調用線程中運行被拒絕的任務;如果執行程序已關閉,則會丟棄該任務。如下:

「漲知識」一篇文章讓你瞭解Java核心線程池

  • 策略-2

直接拋出異常

「漲知識」一篇文章讓你瞭解Java核心線程池

  • 策略-3

什麼都不做直接丟棄

「漲知識」一篇文章讓你瞭解Java核心線程池

  • 策略-4

從任務隊列中移除最早的一個,然後將拒絕的任務重新執行

「漲知識」一篇文章讓你瞭解Java核心線程池

到這裡拒絕策略就說完了,應該都明白了吧,下面我們說下實際中會怎麼用。

如果在任務不是特別多特別重要的情境下,可以在執行拒絕策略發送一個通知事件,通知相關的人查看。

比如以下這種

「漲知識」一篇文章讓你瞭解Java核心線程池

但是當任務特別重要的時候,比如說銀行處理用戶的轉賬信息更新事物的任務時候,那麼這個任務就比較重要了,不可能用這種的,這種對數據要求高的我們都是用Elastic-Job,這種分佈式任務處理框架,任務會首先落數據庫,然後從數據庫中批量讀取任務執行。感興趣的童鞋可以下去自行了解。

五. 任務隊列

Queue:

分為阻塞隊列和非阻塞隊裡

阻塞隊列一共有四套方法分別用來進行insert、remove和examine,當每套方法對應的操作不能馬上執行時會有不同的反應,下面這個表格就分類列出了這些方法:

「漲知識」一篇文章讓你瞭解Java核心線程池

  1. ThrowsException:如果操作不能馬上進行,則拋出異常
  2. SpecialValue:如果操作不能馬上進行,將會返回一個特殊的值,一般是true或者false
  3. Blocks:如果操作不能馬上進行,操作會被阻塞
  4. TimesOut:如果操作不能馬上進行,操作會被阻塞指定的時間,如果指定時間沒執行,則返回一個特殊值,一般是true或者false 需要注意的是,我們不能向BlockingQueue中插入null,否則會報NullPointerException。
  5. LinkedBlockingQueue 無邊界隊裡
  6. PriorityBlockingQueue 排序隊列,內部會排序但是要實現排序接口
  7. SynchronousQueue 同步隊列
  8. ArrayBlockingQueue 阻塞隊裡,內不是數組,有邊界
  9. DelayQueue 延遲隊裡

「漲知識」一篇文章讓你瞭解Java核心線程池

1. Java線程池深度講解(也就是本文)

2. OVAL驗證框架使用

3. ThreadLocal線程隔離深度講解(包含Thread源碼講解,父子本地空間繼承和線程池隔離,最後會講解阿里TransmittableThreadLocal底層實現原理)

4. 分佈式鎖對比(zookeeper鎖和基於redis分佈式鎖)


分享到:


相關文章: