java執行緒池詳解

2021-09-11 03:37:45 字數 4425 閱讀 1747

一、執行緒池狀態

五個狀態: running、shutdown、stop、tidying、terminated

執行緒池的管理使用的atomicinteger實現原子管理,而使用位操作實現執行緒池狀態的管理和執行緒池中線程個數的管理,巧妙的採用了高3位管理狀態,低29位管理個數

// runstate is stored in the high-order bits

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;

private static final int terminated = 3 << count_bits;

private static final int count_bits = integer.size - 3;

private static final int capacity = (1 << count_bits) - 1;

//獲取執行緒池的狀態

private static int runstateof(int c)

//獲取當前執行緒池中線程個數

private static int workercountof(int c)

//重置執行緒池狀態和現場個數

private static int ctlof(int rs, int wc)

running: 執行緒池初始化時的狀態

private final atomicinteger ctl = new atomicinteger(ctlof(running, 0));
shutdown:呼叫shutdown()函式

stop:呼叫shutdownnow()函式

tidying: 嘗試著去terminate

if (ctl.compareandset(c, ctlof(tidying, 0)))  finally 

return;

}

terminated: 從上述**可以看到,結束前我們還可以在terminated()做一些事情,threadpoolexecutor中這個方法是空實現

二、threadpoolexecutor的類體系

executor介面定義了execute方法

executorservice介面定義shutdown和submit方法

abstractexecutorservice抽象方法定義了submit具體實現

threadpoolexecutor是來具體管理執行緒池的相關情況,其次,就是可以繼承abstractexecutorservice自定義實現(目前自己還沒到這水平。。。)

三、threadpoolexecutor建構函式

public threadpoolexecutor(int corepoolsize,

int maximumpoolsize,

long keepalivetime,

timeunit unit,

blockingqueueworkqueue,

threadfactory threadfactory,

rejectedexecutionhandler handler)

1、核心執行緒數

2、最大執行緒數

3、存活時間

4、時間單位

5、佇列

6、執行緒工廠

7、拒絕策略

一般來說,都是自定義的,而executors中定義的各式各樣的執行緒池都是不同的具體引數

四、執行緒池的原始碼

public static void main(string args)
執行的submit時,會進入abstractexecutorservice的submit中

public future> submit(runnable task)
接著執行execute,進入threadpoolexecutor

處理分為三步:

1、如果當前執行緒數小於corepoolsize,則新建worker執行;

2、如果當前現場狀態為running,則將任務加入佇列並新增成功中

2.1 、判斷執行緒池當前狀態是否為running,如果非,則需要移出佇列,並按照拒絕策略拒絕該任務;

2.2、如果當前狀態為running,判斷執行緒池中worker數是否為0,如果為0,則新建worker(不執行改任務?建立既啟動);

2.3、如果當前狀態為running,且worker數大於0,則怎麼辦?worker會不斷得從佇列中取出任務執行,因此只要入隊成功即可

3、如果非running,或任務入隊失敗,則新建worker,新建worker失敗則拒絕該任務。為何還要新建worker呢?可以看看executors.newcachedthreadpool()就是特殊情況

public void execute(runnable command) 

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

else if (!addworker(command, false))

reject(command);

}

以上三個問題的原因,估計都在addworker中解決

首先看看worker,它是乙個內部類,定義在threadpoolexecutor中,且實現了runnable,說明其可以作為執行緒執行

private final class worker

extends abstractqueuedsynchronizer

implements runnable

//執行

public void run()

//實現併發控制

....

}

從上述**,我們可以知道,新建worker的時候,會新建乙個執行緒

回過頭來,在看看addworker()方法

//firsttask 在增加建立核心執行緒或者入隊失敗時firsttask不空,這兩種情況core的值不一樣,具體可以看executor方法

private boolean addworker(runnable firsttask, boolean core)

}boolean workerstarted = false;

boolean workeradded = false;

worker w = null;

try

} finally

if (workeradded)

}} finally

return workerstarted;

}

當新建乙個worker時,會同時啟動它所屬的執行緒

接著看其run方法時,實際上呼叫的runworker方法

final void runworker(worker w)  catch (runtimeexception x)  catch (error x)  catch (throwable x)  finally 

} finally

}completedabruptly = false;

} finally

}

我們都知道,建構函式中有個引數值,keepalivetime,表示執行緒存活時間,那麼什麼時候進行worker**呢?

答案在gettask()中

timedout預設是false

下面的**段的意思是

如果大於最大執行緒數,或者在keepalivetime時間內沒有從佇列中拿到任務,則本worker就不伺候大爺們了

boolean timed = allowcorethreadtimeout || wc > corepoolsize;

if ((wc > maximumpoolsize || (timed && timedout))

&& (wc > 1 || workqueue.isempty()))

try catch (interruptedexception retry)

Java 執行緒池併發程式設計詳解

本博文分為6個部分 1.bizprocessor 具體的事務處理邏輯,被多執行緒呼叫。2.bizasynctaskcall 實現callable介面,用於組裝futuretask。3.bizfuturetask 代表乙個非同步計算任務,用於提交任務非同步執行,並返回計算結果。4.bizexecuto...

Java執行緒池

executors類詳解 此包中所定義的 executor executorservice scheduledexecutorservice threadfactory 和 callable 類的工廠和實用方法。此類支援以下各種方法 建立並返回設定有常用配置字串的 executorservice 的...

Java執行緒池

一 執行緒池 單執行緒 public static void runsinglethreadpool public static void runsinglethreadpoolwithfactory private static class mythreadfactory implements t...