JAVA多執行緒之 執行緒池

2021-07-30 04:42:27 字數 4546 閱讀 4871

執行緒池顧名思義,就是乙個放置執行緒的池子。就跟資料庫連線池差不多。執行緒池通過對併發執行緒的控制,能有效的節省系統資源的浪費,提高系統的效能。

學習執行緒池,先了解一下執行緒池的乙個基本結構:

executor是乙個介面,其中只有乙個方法,就是execute方法。所以executor實際就是乙個執行緒的執行者。

這裡就不把子類的所有方法全部列出來,全部學習一遍,大體可以參照api進行學習。這裡主要學習執行緒池threadpoolexecutor方法開始學習,來了解學習執行緒池的乙個執行原理。

threadpoolexecutor的一些重要屬性

//ctl用來表示執行緒池的執行狀態,和執行緒池中任務的數量。

private

final atomicinteger ctl = new atomicinteger(ctlof(running, 0));

//進製位。最大整數轉換成二進位制的位數

private

static

final

int count_bits = integer.size - 3;

//執行緒池的最大容量2的29次方減1

private

static

final

int capacity = (1

<< count_bits) - 1;

。//執行狀態,能接收任務,並對已經新增的任務進行處理

private

static

final

int running = -1

<< count_bits;

//不能接收新任務,但能處理已經新增的任務

private

static

final

int shutdown = 0

<< count_bits;

//不能接收新任務,也不能處理已經新增的任務,並且中斷已經在處理的任務

private

static

final

int stop = 1

<< count_bits;

private

static

final

int tidying = 2

<< count_bits;

//執行緒池徹底終止,就變成terminated狀態。

private

static

final

int terminated = 3

<< count_bits;

// packing and unpacking ctl

//返回執行緒池的狀態

private

static

intrunstateof(int c)

//返回執行緒池的有效容量

private

static

intworkercountof(int c)

//初始化ctl

private

static

intctlof(int rs, int wc)

//執行緒的阻塞佇列

private

final blockingqueueworkqueue;

//互斥鎖

private

final reentrantlock mainlock = new reentrantlock();

//執行緒工作集

private

final hashsetworkers = new hashset();

//終止條件

private

final condition termination = mainlock.newcondition();

// 執行緒池中線程數量曾經達到過的最大值。

private

int largestpoolsize;

// 已完成任務數量

private

long completedtaskcount;

//執行緒工廠

private

volatile threadfactory threadfactory;

//執行緒被拒絕時的處理策略

private

volatile rejectedexecutionhandler handler;

// 保持執行緒存活時間。

private

volatile

long keepalivetime;

//是否允許"執行緒在空閒狀態時,仍然能夠存活

private

volatile

boolean allowcorethreadtimeout;

//核心執行緒池大小

private

volatile

int corepoolsize;

//執行緒池的最大容量

private

volatile

int maximumpoolsize;

這麼多變數,可能要記住也不是很容易。通過分析execute方法可以更加好的理解工作原理和這些屬性的意義

public

void

execute(runnable command)

//2.如果當前任務數量大於了corepoolsize,並且執行緒池是可執行狀態。就把任務加入到任務佇列workqueue中。 加入佇列之後,再次確認執行緒池的狀態,這個時候狀態不是可執行的,那就把任務從佇列中刪除,並嘗試終止執行緒池。如果是可執行,那麼就檢查執行緒池中工作數量是否為0,如果沒有了,那麼就新增乙個任務為空的執行緒。

if (isrunning(c) && workqueue.offer(command))

//3.如果任務數量大於中心池數量,新增對了也失敗了(這裡佇列是blockingqueue,前面學習過佇列有有界佇列和無界佇列,所以有可能佇列滿了導致新增失敗。活著其它原因),那麼就再進行一次嘗試新增到任務集中去,如果失敗,執行拒絕策略。

else

if (!addworker(command, false))

reject(command);

}

通過上面的步驟學習,可以大致的理一下思路,執行緒池,有乙個中心池容量,這個容量沒有滿,就可以直接新增任務執行,而任務是被 新增到乙個hashset的worker中。如果滿了,就把任務新增到乙個blockingqueue佇列中。都失敗了,就直接執行乙個拒絕策略。所以,就要理解三個東西:

工作集。

任務佇列

拒絕策略。

理解了這三個東西,那麼大致就可以了解執行緒池的乙個基本原理。

工作集 worker

//worker是執行緒池的乙個內部類 整合了aqs,實現了runnable介面。

private

final

class

worker

extends

abstractqueuedsynchronizer

implements

runnable

public

void

run()

protected

boolean

isheldexclusively()

protected

boolean

tryacquire(int unused)

return

false;

}protected

boolean

tryrelease(int unused)

public

void

lock()

public

boolean

trylock()

public

void

unlock()

public

boolean

islocked()

void interruptifstarted() catch (securityexception ignore) }}

}

工作集的就是把任務通過執行緒工廠建立乙個該任務的執行緒並執行。

* 任務佇列*

從定義上看我們知道任務佇列是乙個blockingqueue。所以執行緒池中的任務佇列可以是任意blockingqueue的子類。但是常用執行緒池中常用的的是arrayblockingqueue,linkedblockingqueue,synchronousqueue .下一節會學習重用的執行緒池型別。

拒絕策略大致了解學習了執行緒池的乙個主要執行過程和基本原理。下一節將會學習jdk自帶的幾種執行緒池,更加進一步學習和理解執行緒池。

多執行緒之執行緒池

執行緒框架關係 executor 介面 executorservice 介面 繼承 executor abstractexecutorservice 抽象類 實現 executorservice threadpoolexecutor 繼承abstractexecutorservice 過載一系列方法...

多執行緒之執行緒池

首先說一說執行緒池的優點 方便管理,監控執行緒狀態 提高執行緒響應速度 執行緒可以重複使用 executorservice普通排程池核心介面 submit runnable callable future execute runnable void 執行緒池工作流程 當任務到達執行緒池時的工作順序,...

javaSE 多執行緒之執行緒池

1 使用語法 publicstaticvoiduseexecutorservice executorservice shutdown 輸出 pool 1 thread 3 pool 1 thread 2 pool 1 thread 1 pool 1 thread 3 pool 1 thread 2 ...