Java基礎(chǔ)-并發(fā)編程-線程執(zhí)行器executor

Java工程師知識(shí)樹(shù) / Java基礎(chǔ)


線程實(shí)現(xiàn)方式

Thread、Runnable、Callable

//實(shí)現(xiàn)Runnable接口的類將被Thread執(zhí)行,表示一個(gè)基本任務(wù)
public interface Runnable {    
    //run方法就是它所有內(nèi)容,就是實(shí)際執(zhí)行的任務(wù)    
    public abstract void run();
}
//Callable同樣是任務(wù),與Runnable接口的區(qū)別在于它接口泛型,同時(shí)它執(zhí)行任務(wù)候帶有返回值;
//Callable的使用通過(guò)外層封裝成Future來(lái)使用
public interface Callable<V> {    
    //相對(duì)于run方法,call方法帶有返回值    
    V call() throws Exception;
}

注意:?jiǎn)?dòng)Thread線程只能用start(JNI方法)來(lái)啟動(dòng),start方法通知虛擬機(jī),虛擬機(jī)通過(guò)調(diào)用器映射到底層操作系統(tǒng),通過(guò)操作系統(tǒng)來(lái)創(chuàng)建線程來(lái)執(zhí)行當(dāng)前任務(wù)的run方法

Executor框架

Executor接口是線程池框架中最基礎(chǔ)的部分,定義了一個(gè)用于執(zhí)行Runnable的execute方法。從圖中可以看出Exectuor下有一個(gè)重要的子接口ExecutorService,其中定義了線程池的具體行為:

  • execute(Runnable runnable):執(zhí)行Runnable類型的任務(wù)

  • submit(task):用來(lái)提交Callable或者Runnable任務(wù),并返回代表此任務(wù)的Future對(duì)象

  • shutdown():在完成已經(jīng)提交的任務(wù)后封閉辦事,不在接管新的任務(wù)

  • shutdownNow():停止所有正在履行的任務(wù)并封閉辦事

  • isTerminated():是一個(gè)鉤子函數(shù),測(cè)試是否所有任務(wù)都履行完畢了

  • isShutdown():是一個(gè)鉤子函數(shù),測(cè)試是否該ExecutorService是否被關(guān)閉

ExecutorService中的重點(diǎn)屬性:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

ctl:對(duì)線程池的運(yùn)行狀態(tài)和線程池中有效線程的數(shù)量進(jìn)行控制的一個(gè)字段,它包含兩部分信息:線程池的運(yùn)行狀態(tài)(runState)和線程池內(nèi)有效線程的數(shù)量(workerCount)。

這里可以看到,使用Integer類型來(lái)保存,高3位保存runState,低29位保存workerCount。COUNT_BITS 就是29,CAPACITY 就是1左移29位減1(29個(gè)1),這個(gè)常量表示workerCount的上限值,大約是5億。

ctl相關(guān)方法:

//獲取運(yùn)行狀態(tài)
private static int runStateOf(int c){ 
    return c & ~CAPACITY; 
}
//獲取活動(dòng)線程數(shù)
private static int workerCountOf(int c)  { 
    return c & CAPACITY; 
}
//獲取運(yùn)行狀態(tài)和活動(dòng)線程數(shù)的值
private static int ctlOf(int rs, int wc) { 
    return rs | wc; 
}

線程池的狀態(tài):

    RUNNING = -1 << COUNT_BITS? //高3位為111
    SHUTDOWN = 0 << COUNT_BITS? //高3位為000
    STOP = 1 << COUNT_BITS? //高3位為001
    TIDYING = 2 << COUNT_BITS? //高3位為010
    TERMINATED = 3 << COUNT_BITS? //高3位為011

線程池實(shí)例的狀態(tài)

1、RUNNING

  • 狀態(tài)說(shuō)明:線程池處于RUNNING狀態(tài),能夠接收新任務(wù),以及對(duì)已添加的任務(wù)進(jìn)行處理。
  • 狀態(tài)切換:線程池的初始化狀態(tài)是RUNNING。換句話說(shuō),線程池一旦被創(chuàng)建,就處于RUNNING狀態(tài),并且線程池中的任務(wù)數(shù)為0。

2、SHUTDOWN

  • 狀態(tài)說(shuō)明:線程池處于SHUTDOWN狀態(tài),不接收新任務(wù),能夠處理已經(jīng)添加的任務(wù)。
  • 狀態(tài)切換:調(diào)用shutdown()方法時(shí),線程池由RUNNING -> SHUTDOWN。

3、STOP

  • 狀態(tài)說(shuō)明:線程池處于STOP狀態(tài),不接收新任務(wù),不處理已提交的任務(wù),并且會(huì)中斷正在處理的任務(wù)。
  • 狀態(tài)切換:調(diào)用線程池中的shutdownNow()方法時(shí),線程池由(RUNNING or SHUTDOWN) -> STOP。

4、TIDYING

  • 狀態(tài)說(shuō)明:當(dāng)所有的任務(wù)已經(jīng)停止,ctl記錄“任務(wù)數(shù)量”為0,線程池會(huì)變?yōu)門IDYING狀態(tài)。當(dāng)線程池處于TIDYING狀態(tài)時(shí),會(huì)執(zhí)行鉤子函數(shù) terminated()。terminated()在ThreadPoolExecutor類中是空, 的,若用戶想在線程池變?yōu)門IDYING時(shí),進(jìn)行相應(yīng)處理,可以通過(guò)重載 terminated()函數(shù)來(lái)實(shí)現(xiàn)。
  • 狀態(tài)切換:當(dāng)線程池在SHUTDOWN狀態(tài)下,阻塞隊(duì)列為空并且線程池中執(zhí)行任務(wù)也為空時(shí),就會(huì)由SHUTDOWN -> TIDYING。當(dāng)線程池在STOP狀態(tài)下,線程池中執(zhí)行的任務(wù)為空時(shí),就會(huì)由STOP-> TIDYING。

5、TERMINATED

  • 狀態(tài)說(shuō)明:線程池線程池徹底停止,線程池處于TERMINATED狀態(tài),
  • 狀態(tài)切換:線程池處于TIDYING狀態(tài)時(shí),執(zhí)行完terminated()之后, 就會(huì)由TIDYING->TERMINATED。

線程池使用

線程池使用

ThreadPoolExecutor構(gòu)造方法

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
}

任務(wù)的提交流程

執(zhí)行圖:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容