自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用 Java Executors 創(chuàng)建線程池的九種方法

開(kāi)發(fā) 前端
學(xué)習(xí)線程池時(shí),Executors類(lèi)不可或缺。掌握其用法、原理和適用場(chǎng)景,有助于在實(shí)際項(xiàng)目開(kāi)發(fā)中順利應(yīng)用。以下是一些常用方法,我將逐一解釋。

在 Java 中,Executors類(lèi)提供了多種靜態(tài)工廠方法來(lái)創(chuàng)建不同類(lèi)型的線程池。學(xué)習(xí)線程池時(shí),Executors類(lèi)不可或缺。掌握其用法、原理和適用場(chǎng)景,有助于在實(shí)際項(xiàng)目開(kāi)發(fā)中順利應(yīng)用。以下是一些常用方法,我將逐一解釋。

這些方法提供了靈活的方式來(lái)創(chuàng)建和管理線程池,以滿足不同的并發(fā)需求。下面,我將詳細(xì)介紹這 9 種方法的實(shí)現(xiàn)和使用場(chǎng)景。

1. newCachedThreadPool()

newCachedThreadPool方法是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)可緩存線程池,可根據(jù)需要?jiǎng)討B(tài)創(chuàng)建新線程,并終止在一定時(shí)間內(nèi)未使用的空閑線程。

(1) 實(shí)現(xiàn)原理

  • 線程創(chuàng)建:當(dāng)向線程池提交任務(wù)時(shí),如果當(dāng)前線程數(shù)小于核心池大小,將創(chuàng)建新線程。
  • 線程重用:如果當(dāng)前線程數(shù)等于核心池大小,新任務(wù)將被放入任務(wù)隊(duì)列等待執(zhí)行。
  • 線程終止:空閑線程在指定時(shí)間(默認(rèn)為 60 秒)內(nèi)未被使用將被終止,以減少資源消耗。

(2) 源代碼分析

在 Java 的java.util.concurrent包中,Executors類(lèi)并不直接提供newCachedThreadPool的實(shí)現(xiàn)。相反,它使用ThreadPoolExecutor構(gòu)造函數(shù)。以下是ThreadPoolExecutor調(diào)用的示例:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                   60L, TimeUnit.SECONDS,
                                   new SynchronousQueue());
}

(3) 參數(shù)解釋

  • corePoolSize:核心線程數(shù),這里設(shè)置為 0,表示線程池不保留任何核心線程。
  • maximumPoolSize:最大線程數(shù),設(shè)置為Integer.MAX_VALUE,理論上允許無(wú)限數(shù)量的線程。
  • keepAliveTime:多余空閑線程在終止前等待新任務(wù)的最長(zhǎng)時(shí)間,這里設(shè)置為 60 秒。
  • unit:keepAliveTime參數(shù)的時(shí)間單位,這里是秒。
  • workQueue:任務(wù)隊(duì)列。這里使用SynchronousQueue,這是一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列,要求每個(gè)插入操作都等待相應(yīng)的移除操作。

(4) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用newCachedThreadPool時(shí),創(chuàng)建一個(gè)ThreadPoolExecutor實(shí)例。
  • 任務(wù)提交:向線程池提交任務(wù)時(shí),池檢查是否有空閑線程可用于執(zhí)行任務(wù)。
  • 線程創(chuàng)建:如果沒(méi)有空閑線程且當(dāng)前線程數(shù)小于maximumPoolSize,則創(chuàng)建新線程來(lái)執(zhí)行任務(wù)。
  • 任務(wù)隊(duì)列:如果當(dāng)前線程數(shù)已達(dá)到maximumPoolSize,任務(wù)將被放入SynchronousQueue等待執(zhí)行。
  • 線程重用:線程完成任務(wù)后,不會(huì)立即終止,而是嘗試從SynchronousQueue獲取新任務(wù)。
  • 線程終止:如果線程在keepAliveTime內(nèi)未收到新任務(wù),將終止。

這種設(shè)計(jì)使newCachedThreadPool非常適合處理大量短期異步任務(wù),因?yàn)樗梢詣?dòng)態(tài)調(diào)整線程數(shù)量以適應(yīng)不同的工作負(fù)載。然而,由于它可以創(chuàng)建無(wú)限數(shù)量的線程,因此必須考慮任務(wù)的特性和系統(tǒng)資源限制,以防止資源耗盡。

(5) 使用場(chǎng)景

適用于執(zhí)行許多短期異步任務(wù),特別是當(dāng)任務(wù)的執(zhí)行時(shí)間不確定時(shí)。例如,處理 Web 服務(wù)器上的大量并發(fā)請(qǐng)求或異步日志記錄。

2. newFixedThreadPool(int nThreads)

newFixedThreadPool(int nThreads)方法是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)具有固定線程數(shù)的線程池,確保池中的線程數(shù)量保持不變。

(1) 實(shí)現(xiàn)原理

  • 固定線程數(shù):線程池中的線程數(shù)量始終保持為nThreads。
  • 任務(wù)隊(duì)列:提交到池中的任務(wù)首先由核心線程執(zhí)行。如果所有核心線程都忙碌,新任務(wù)將被放入阻塞隊(duì)列等待執(zhí)行。
  • 線程重用:池中的線程會(huì)被重用;完成一個(gè)任務(wù)后,線程將立即嘗試從隊(duì)列中獲取下一個(gè)任務(wù)執(zhí)行。

(2) 源代碼分析

newFixedThreadPool方法通過(guò)調(diào)用ThreadPoolExecutor類(lèi)的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。以下是ThreadPoolExecutor調(diào)用的示例:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(
        nThreads, 
        nThreads, 
        0L,      
        TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue() 
    );
}

(3) 參數(shù)解釋

  • corePoolSize:核心線程數(shù),設(shè)置為nThreads,表示池始終有nThreads個(gè)線程。
  • maximumPoolSize:最大線程數(shù),也設(shè)置為nThreads,確保池大小不超過(guò)nThreads。
  • keepAliveTime:多余空閑線程在終止前等待新任務(wù)的最長(zhǎng)時(shí)間,這里設(shè)置為 0,表示任何超過(guò)核心池大小的線程將立即終止。
  • unit:keepAliveTime參數(shù)的時(shí)間單位,這里是毫秒。
  • workQueue:任務(wù)隊(duì)列。這里使用LinkedBlockingQueue,這是一個(gè)基于鏈表的阻塞隊(duì)列,可以存儲(chǔ)任意數(shù)量的任務(wù)。

(4) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用newFixedThreadPool時(shí),創(chuàng)建一個(gè)ThreadPoolExecutor實(shí)例。
  • 任務(wù)提交:向池提交任務(wù)時(shí),檢查是否有空閑核心線程可立即執(zhí)行任務(wù)。
  • 任務(wù)隊(duì)列:如果所有核心線程都忙碌,新任務(wù)將被放入LinkedBlockingQueue等待執(zhí)行。
  • 線程重用:核心線程完成任務(wù)后,將嘗試從LinkedBlockingQueue獲取新任務(wù)繼續(xù)執(zhí)行。
  • 線程數(shù)控制:由于keepAliveTime設(shè)置為 0,任何超過(guò)核心池大小的線程將立即終止,確保池中的線程數(shù)量不超過(guò)nThreads。

這種設(shè)計(jì)使newFixedThreadPool非常適合處理大量穩(wěn)定的任務(wù)流,因?yàn)樗_保任務(wù)由固定數(shù)量的線程并行執(zhí)行,避免線程不受控制地增長(zhǎng)。然而,由于池大小是固定的,如果任務(wù)提交速率超過(guò)池的處理能力,任務(wù)可能會(huì)在隊(duì)列中長(zhǎng)時(shí)間等待。因此,使用newFixedThreadPool時(shí),根據(jù)任務(wù)的特性和預(yù)期工作負(fù)載設(shè)置nThreads非常重要。

(5) 使用場(chǎng)景

適用于執(zhí)行大量長(zhǎng)時(shí)間運(yùn)行的任務(wù),且需要固定線程數(shù)量的情況。例如,同時(shí)運(yùn)行多個(gè)數(shù)據(jù)加載或數(shù)據(jù)處理任務(wù),同時(shí)限制并發(fā)以避免資源過(guò)載。

3. newSingleThreadExecutor()

newSingleThreadExecutor方法是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)單線程執(zhí)行器,確保所有任務(wù)按提交順序依次執(zhí)行,使用單個(gè)線程。

(1) 實(shí)現(xiàn)原理

  • 單線程執(zhí)行:線程池只包含一個(gè)線程,確保所有任務(wù)由這個(gè)單線程按順序執(zhí)行。
  • 任務(wù)隊(duì)列:如果在單線程忙碌時(shí)提交新任務(wù),任務(wù)將被放入阻塞隊(duì)列等待執(zhí)行。
  • 線程重用:?jiǎn)尉€程會(huì)被重用;完成一個(gè)任務(wù)后,它將立即嘗試從隊(duì)列中獲取下一個(gè)任務(wù)執(zhí)行。

(2) 源代碼分析

newSingleThreadExecutor方法通過(guò)調(diào)用ThreadPoolExecutor類(lèi)的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。以下是ThreadPoolExecutor調(diào)用的示例:

public static ExecutorService newSingleThreadExecutor() {
    return new ThreadPoolExecutor(
        1, 
        1, 
        0L, TimeUnit.MILLISECONDS, 
        new LinkedBlockingQueue() 
    );
}

(3) 參數(shù)解釋

  • corePoolSize:核心線程數(shù),設(shè)置為 1,表示池始終有一個(gè)核心線程。
  • maximumPoolSize:最大線程數(shù),也設(shè)置為 1,確保池大小不超過(guò)一個(gè)線程。
  • keepAliveTime:多余空閑線程在終止前等待新任務(wù)的最長(zhǎng)時(shí)間,這里設(shè)置為 0,表示線程空閑時(shí)將立即終止。
  • unit:keepAliveTime參數(shù)的時(shí)間單位,這里是毫秒。
  • workQueue:任務(wù)隊(duì)列。這里使用LinkedBlockingQueue,這是一個(gè)可以存儲(chǔ)任意數(shù)量任務(wù)的阻塞隊(duì)列。

(4) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用newSingleThreadExecutor時(shí),創(chuàng)建一個(gè)ThreadPoolExecutor實(shí)例。
  • 任務(wù)提交:向池提交任務(wù)時(shí),如果核心線程空閑,它將立即執(zhí)行任務(wù);如果核心線程忙碌,任務(wù)將被放入LinkedBlockingQueue等待。
  • 順序執(zhí)行:由于只有一個(gè)線程,所有任務(wù)按提交順序執(zhí)行。
  • 任務(wù)隊(duì)列:如果核心線程正在執(zhí)行任務(wù),新任務(wù)將被放入LinkedBlockingQueue等待。
  • 線程重用:核心線程完成任務(wù)后,將嘗試從LinkedBlockingQueue獲取新任務(wù)繼續(xù)執(zhí)行。
  • 線程數(shù)控制:由于keepAliveTime設(shè)置為 0,核心線程在沒(méi)有任務(wù)可執(zhí)行時(shí)將立即終止。然而,因?yàn)閏orePoolSize和maximumPoolSize都為 1,線程池將立即重新創(chuàng)建一個(gè)新線程。

這種設(shè)計(jì)使newSingleThreadExecutor非常適合需要保證任務(wù)順序執(zhí)行的場(chǎng)景,例如任務(wù)有依賴關(guān)系或必須按特定順序執(zhí)行的情況。此外,由于只有一個(gè)線程,它避免了多線程環(huán)境中固有的并發(fā)問(wèn)題。然而,單線程執(zhí)行也限制了并行處理能力;如果一個(gè)任務(wù)執(zhí)行時(shí)間較長(zhǎng),后續(xù)任務(wù)可能會(huì)經(jīng)歷顯著的延遲。因此,使用newSingleThreadExecutor時(shí),考慮任務(wù)的性質(zhì)和順序執(zhí)行的要求非常重要。

(5) 使用場(chǎng)景

  • 保證順序執(zhí)行:適用于需要任務(wù)按特定順序執(zhí)行的場(chǎng)景,例如隊(duì)列中消息或事件的順序處理。
  • 單后臺(tái)線程執(zhí)行定期任務(wù):適用于需要單個(gè)后臺(tái)線程持續(xù)處理定期任務(wù)的情況。

通過(guò)使用newSingleThreadExecutor,開(kāi)發(fā)人員可以確保任務(wù)按提交順序執(zhí)行,而無(wú)需管理多個(gè)線程的復(fù)雜性和潛在問(wèn)題。

4. newScheduledThreadPool(int corePoolSize)

newScheduledThreadPool方法是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法用于創(chuàng)建一個(gè)固定大小的線程池,支持執(zhí)行定時(shí)和周期性任務(wù)。

(1) 實(shí)現(xiàn)原理

  • 定時(shí)任務(wù):線程池可以執(zhí)行具有指定延遲或固定間隔的任務(wù)。
  • 固定線程數(shù):池中的線程數(shù)量限制為corePoolSize指定的大小。
  • 任務(wù)隊(duì)列:任務(wù)首先由核心線程執(zhí)行。如果所有核心線程都忙碌,新任務(wù)將被放入延遲隊(duì)列等待執(zhí)行。

(2) 源代碼分析

newScheduledThreadPool方法通過(guò)調(diào)用ScheduledThreadPoolExecutor類(lèi)的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。以下是調(diào)用示例:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

ScheduledThreadPoolExecutor是ThreadPoolExecutor的子類(lèi),專(zhuān)門(mén)用于執(zhí)行定時(shí)任務(wù)。ScheduledThreadPoolExecutor構(gòu)造函數(shù)的corePoolSize參數(shù)定義了池中核心線程的數(shù)量。

內(nèi)部,ScheduledThreadPoolExecutor使用DelayedWorkQueue作為其任務(wù)隊(duì)列,該隊(duì)列根據(jù)任務(wù)的預(yù)定執(zhí)行時(shí)間對(duì)任務(wù)進(jìn)行排序。

(3) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用newScheduledThreadPool時(shí),創(chuàng)建一個(gè)ScheduledThreadPoolExecutor實(shí)例。
  • 任務(wù)提交:向池提交任務(wù)時(shí),根據(jù)其預(yù)定執(zhí)行時(shí)間將其放入DelayedWorkQueue。
  • 任務(wù)調(diào)度:池中的線程從DelayedWorkQueue中獲取任務(wù),并在預(yù)定時(shí)間到達(dá)時(shí)執(zhí)行它們。
  • 線程重用:完成任務(wù)的線程將嘗試從DelayedWorkQueue獲取下一個(gè)任務(wù)。
  • 線程數(shù)控制:如果任務(wù)數(shù)量超過(guò)核心線程的處理能力,ScheduledThreadPoolExecutor將創(chuàng)建新線程來(lái)幫助處理任務(wù),最多達(dá)到corePoolSize定義的限制。

(4) 特性

  • 線程工廠:ScheduledThreadPoolExecutor允許設(shè)置線程工廠來(lái)創(chuàng)建具有特定屬性的線程。
  • 拒絕執(zhí)行處理程序:它允許設(shè)置RejectedExecutionHandler來(lái)處理無(wú)法接受的任務(wù)(例如,當(dāng)池關(guān)閉或任務(wù)隊(duì)列已滿時(shí))。
  • 關(guān)閉行為:與ThreadPoolExecutor不同,ScheduledThreadPoolExecutor的shutdown和shutdownNow方法不會(huì)等待延遲任務(wù)完成。

newScheduledThreadPool方法非常適合需要執(zhí)行定時(shí)任務(wù)的場(chǎng)景,例如周期性后臺(tái)任務(wù)或計(jì)劃在特定時(shí)間運(yùn)行的任務(wù)。然而,由于它基于固定大小的線程池,在高負(fù)載下,任務(wù)可能會(huì)排隊(duì)等待執(zhí)行。因此,在設(shè)計(jì)時(shí)考慮適當(dāng)?shù)腸orePoolSize以滿足性能要求非常重要。

(5) 使用場(chǎng)景

  • 周期性任務(wù)執(zhí)行:適用于需要定期執(zhí)行任務(wù)的場(chǎng)景,例如定期數(shù)據(jù)備份或周期性狀態(tài)檢查。
  • 延遲任務(wù)執(zhí)行:適用于需要在未來(lái)某個(gè)時(shí)間點(diǎn)執(zhí)行的任務(wù),例如發(fā)送提醒或計(jì)劃更新。

通過(guò)使用newScheduledThreadPool,開(kāi)發(fā)人員可以有效地管理和調(diào)度需要在固定間隔或特定時(shí)間執(zhí)行的任務(wù),確保任務(wù)由固定數(shù)量的線程正確處理。

5. newWorkStealingPool(int parallelism)

newWorkStealingPool(int parallelism)方法是 Java 8 中引入的java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)工作竊取線程池,可提高并行任務(wù)的執(zhí)行效率,特別是在多處理器系統(tǒng)上。

(1) 實(shí)現(xiàn)原理

  • 工作竊?。涸诠ぷ鞲`取線程池中,每個(gè)線程都有自己的任務(wù)隊(duì)列。當(dāng)一個(gè)線程完成其任務(wù)時(shí),它會(huì)嘗試從其他線程的隊(duì)列中“竊取”任務(wù)。
  • 并行級(jí)別:線程池的大小由parallelism參數(shù)確定,通常等于主機(jī)上的處理器核心數(shù)量。
  • 動(dòng)態(tài)調(diào)整:工作竊取線程池可以動(dòng)態(tài)添加或刪除線程,以適應(yīng)任務(wù)負(fù)載和線程利用率。

(2) 源代碼分析

newWorkStealingPool方法通過(guò)調(diào)用ForkJoinPool類(lèi)的靜態(tài)工廠方法來(lái)實(shí)現(xiàn)。以下是調(diào)用示例:

public static ExecutorService newWorkStealingPool(int parallelism) {
    return new ForkJoinPool(
        parallelism,
        ForkJoinPool.defaultForkJoinWorkerThreadFactory,
        null, 
        false 
    );
}

(3) 參數(shù)解釋

  • parallelism:并行級(jí)別,即線程池中的線程數(shù)量。
  • ForkJoinPool.defaultForkJoinWorkerThreadFactory:用于創(chuàng)建線程的默認(rèn)線程工廠。
  • null:未捕獲異常處理程序,這里未指定,因此如果任務(wù)拋出未捕獲異常,它將傳播到ForkJoinTask的調(diào)用者。
  • false:表示這不是異步任務(wù)。

ForkJoinPool內(nèi)部使用ForkJoinWorkerThread來(lái)執(zhí)行任務(wù),每個(gè)線程都有一個(gè)ForkJoinQueue來(lái)存儲(chǔ)任務(wù)。

(4) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用newWorkStealingPool時(shí),創(chuàng)建一個(gè)ForkJoinPool實(shí)例。
  • 任務(wù)提交:向池提交任務(wù)時(shí),任務(wù)被放入調(diào)用線程的本地隊(duì)列。
  • 任務(wù)執(zhí)行:每個(gè)線程首先嘗試從其本地隊(duì)列執(zhí)行任務(wù)。
  • 工作竊?。喝绻镜仃?duì)列為空,線程嘗試從其他線程的隊(duì)列中竊取任務(wù)。
  • 動(dòng)態(tài)調(diào)整:線程池可以根據(jù)需要?jiǎng)討B(tài)添加或刪除線程。

(5) 特性

  • 工作竊?。哼@種機(jī)制特別適合工作負(fù)載不均勻分布的情況,因?yàn)樗鼫p少了空閑時(shí)間并提高了資源利用率。
  • 并行計(jì)算:適合可以分解為多個(gè)子任務(wù)的并行計(jì)算任務(wù),因?yàn)槿蝿?wù)可以被分割并將子任務(wù)提交到線程池。
  • 減少競(jìng)爭(zhēng):由于每個(gè)線程都有自己的隊(duì)列,鎖競(jìng)爭(zhēng)減少,提高了并發(fā)性能。

newWorkStealingPool非常適合需要高并發(fā)和高吞吐量的場(chǎng)景,特別是在多處理器系統(tǒng)上。然而,由于工作竊取機(jī)制,它可能不適合任務(wù)執(zhí)行時(shí)間非常短或任務(wù)數(shù)量非常少的場(chǎng)景,因?yàn)楦`取本身可能會(huì)引入額外的開(kāi)銷(xiāo)。

(6) 使用場(chǎng)景

  • 不均勻工作負(fù)載:適用于工作負(fù)載不均勻或可以分解為多個(gè)較小任務(wù)的任務(wù),如圖像處理或數(shù)據(jù)分析。
  • 多核處理器利用:有效利用多核處理器的所有核心。

通過(guò)使用newWorkStealingPool,開(kāi)發(fā)人員可以有效地管理和執(zhí)行并行任務(wù),充分利用多核處理器的能力并提高并發(fā)應(yīng)用程序的性能。

6. newSingleThreadScheduledExecutor()

newSingleThreadScheduledExecutor是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)單線程調(diào)度執(zhí)行器,可調(diào)度命令在給定延遲后運(yùn)行或定期執(zhí)行。

(1) 實(shí)現(xiàn)原理

  • 單線程執(zhí)行:執(zhí)行器確保所有任務(wù)在單個(gè)線程中按順序執(zhí)行,維護(hù)任務(wù)執(zhí)行順序。
  • 定時(shí)任務(wù):支持延遲和定期任務(wù)執(zhí)行。
  • 任務(wù)隊(duì)列:所有任務(wù)首先被放入任務(wù)隊(duì)列,然后由單個(gè)線程按順序執(zhí)行。

(2) 源代碼分析

newSingleThreadScheduledExecutor方法通過(guò)調(diào)用ScheduledThreadPoolExecutor類(lèi)的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。以下是調(diào)用示例:

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new ScheduledThreadPoolExecutor(1);
}

這里,ScheduledThreadPoolExecutor是ExecutorService的一個(gè)實(shí)現(xiàn),專(zhuān)門(mén)用于執(zhí)行定時(shí)任務(wù)。構(gòu)造函數(shù)有一個(gè)參數(shù),即核心池大小。將其設(shè)置為 1 表示這是一個(gè)單線程執(zhí)行器。

ScheduledThreadPoolExecutor內(nèi)部使用DelayedWorkQueue作為任務(wù)隊(duì)列。此隊(duì)列可以根據(jù)任務(wù)的預(yù)定執(zhí)行時(shí)間對(duì)任務(wù)進(jìn)行排序。

(3) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用newSingleThreadScheduledExecutor時(shí),創(chuàng)建一個(gè)核心池大小為 1 的ScheduledThreadPoolExecutor實(shí)例。
  • 任務(wù)提交:向執(zhí)行器提交任務(wù)時(shí),它被包裝成ScheduledFutureTask或RunnableScheduledFuture并放入DelayedWorkQueue。
  • 任務(wù)調(diào)度:?jiǎn)尉€程不斷從DelayedWorkQueue獲取任務(wù),并在預(yù)定時(shí)間執(zhí)行它們。如果執(zhí)行時(shí)間已到,任務(wù)將被執(zhí)行;如果未到,線程將等待直到執(zhí)行時(shí)間到達(dá)。
  • 順序執(zhí)行:由于只有一個(gè)線程,所有任務(wù)按提交順序執(zhí)行。
  • 定期任務(wù):對(duì)于需要定期執(zhí)行的任務(wù),執(zhí)行器在每次執(zhí)行后重新計(jì)算下一次執(zhí)行時(shí)間,并將任務(wù)放回隊(duì)列。

(4) 特性

  • 順序維護(hù):newSingleThreadScheduledExecutor非常適合需要維護(hù)任務(wù)順序的場(chǎng)景,例如任務(wù)有依賴關(guān)系或特定順序的情況。
  • 并發(fā)簡(jiǎn)化:只有一個(gè)線程避免了并發(fā)問(wèn)題,簡(jiǎn)化了任務(wù)同步和狀態(tài)管理。
  • 定時(shí)執(zhí)行:它為任務(wù)提供了強(qiáng)大的調(diào)度功能,例如定期維護(hù)或后臺(tái)任務(wù)。

(5) 使用場(chǎng)景

  • 順序任務(wù)執(zhí)行:適用于任務(wù)需要按特定順序執(zhí)行或有依賴關(guān)系的場(chǎng)景。
  • 定時(shí)后臺(tái)任務(wù):適用于需要定期執(zhí)行的任務(wù),例如定期系統(tǒng)檢查或維護(hù)任務(wù)。

7. privilegedThreadFactory()

privilegedThreadFactory是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)線程工廠,生成具有特權(quán)訪問(wèn)權(quán)限的線程。這些線程可以訪問(wèn)系統(tǒng)屬性、加載系統(tǒng)庫(kù)和訪問(wèn)文件系統(tǒng)。

(1) 實(shí)現(xiàn)原理

  • 特權(quán)訪問(wèn):此工廠創(chuàng)建的線程有權(quán)訪問(wèn)系統(tǒng)資源,如加載系統(tǒng)屬性和庫(kù)。
  • 線程創(chuàng)建:線程工廠創(chuàng)建新的線程實(shí)例,這些實(shí)例繼承創(chuàng)建它們的線程的上下文。

(2) 源代碼分析

privilegedThreadFactory方法的實(shí)現(xiàn)細(xì)節(jié)在標(biāo)準(zhǔn) Java 庫(kù)中未公開(kāi)暴露。然而,我們可以通過(guò)檢查其一般工作方式來(lái)理解其功能。以下是privilegedThreadFactory方法可能的調(diào)用示例:

public static ThreadFactory privilegedThreadFactory() {
    return new PrivilegedThreadFactory();
}

這里,PrivilegedThreadFactory是Executors類(lèi)中的私有靜態(tài)內(nèi)部類(lèi),實(shí)現(xiàn)了ThreadFactory接口。ThreadFactory接口定義了newThread(Runnable r)方法用于創(chuàng)建新線程。

(3) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用privilegedThreadFactory方法時(shí),返回一個(gè)新的PrivilegedThreadFactory實(shí)例。
  • 線程創(chuàng)建:當(dāng)使用此工廠創(chuàng)建線程時(shí),它調(diào)用newThread(Runnable r)方法。
  • 特權(quán)訪問(wèn):在newThread(Runnable r)方法實(shí)現(xiàn)中,使用AccessController.doPrivileged方法確保新創(chuàng)建的線程具有特權(quán)訪問(wèn)權(quán)限。
  • 上下文繼承:新線程通常繼承創(chuàng)建它的線程的上下文,包括類(lèi)加載器和其他設(shè)置。

(4) 示例

雖然我們無(wú)法查看privilegedThreadFactory的精確實(shí)現(xiàn),但我們可以提供一個(gè)示例實(shí)現(xiàn)來(lái)演示如何創(chuàng)建特權(quán)線程:

public class PrivilegedThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        return AccessController.doPrivileged(new PrivilegedAction<>() {
            @Override
            public Thread run() {
                return new Thread(r);
            }
        });
    }
}

在這個(gè)示例中,PrivilegedAction是一個(gè)實(shí)現(xiàn)PrivilegedAction接口的匿名類(lèi),其中run方法創(chuàng)建一個(gè)新線程。AccessController.doPrivileged方法執(zhí)行一個(gè)特權(quán)操作,以確保線程創(chuàng)建過(guò)程具有必要的權(quán)限。

(5) 特性

  • 特權(quán)訪問(wèn):使用privilegedThreadFactory創(chuàng)建的線程可以訪問(wèn)敏感系統(tǒng)資源,適用于需要此類(lèi)訪問(wèn)的應(yīng)用程序。
  • 簡(jiǎn)化安全:使用AccessController.doPrivileged確保線程在執(zhí)行期間被授予適當(dāng)?shù)陌踩珯?quán)限。
  • 上下文繼承:新線程繼承其父線程的上下文,包括類(lèi)加載器和其他安全設(shè)置。

(6) 使用場(chǎng)景

  • 訪問(wèn)系統(tǒng)資源:適用于需要線程具有更高權(quán)限以訪問(wèn)系統(tǒng)屬性或執(zhí)行文件 I/O 操作的應(yīng)用程序。
  • 安全敏感操作:確保執(zhí)行安全敏感操作的線程具有必要的權(quán)限,以避免安全異常。

8. defaultThreadFactory()

defaultThreadFactory是 Java java.util.concurrent包中Executors類(lèi)的靜態(tài)工廠方法。此方法創(chuàng)建一個(gè)默認(rèn)線程工廠,生成具有標(biāo)準(zhǔn)屬性的線程,沒(méi)有特殊權(quán)限。

(1) 實(shí)現(xiàn)原理

  • 標(biāo)準(zhǔn)線程創(chuàng)建:線程工廠生成具有默認(rèn)屬性的線程。
  • 線程命名:創(chuàng)建的線程具有默認(rèn)名稱前綴,通常形式為“pool-x-thread-y”,其中 x 和 y 是數(shù)字。
  • 線程優(yōu)先級(jí):線程優(yōu)先級(jí)設(shè)置為T(mén)hread.NORM_PRIORITY,這是 Java 線程的默認(rèn)優(yōu)先級(jí)。
  • 非守護(hù)線程:創(chuàng)建的線程是非守護(hù)線程,這意味著它們的存在將阻止 JVM 退出。

(2) 源代碼分析

defaultThreadFactory方法的詳細(xì)實(shí)現(xiàn)未完全暴露,但我們可以從ThreadFactory接口和一些可用的源代碼片段推斷其行為。

以下是defaultThreadFactory方法的典型調(diào)用:

public static ThreadFactory defaultThreadFactory() {
    return new DefaultThreadFactory();
}

DefaultThreadFactory是Executors類(lèi)中的私有靜態(tài)內(nèi)部類(lèi),實(shí)現(xiàn)了ThreadFactory接口。ThreadFactory接口定義了newThread(Runnable r)方法用于創(chuàng)建新線程。

(3) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用defaultThreadFactory方法時(shí),返回一個(gè)新的DefaultThreadFactory實(shí)例。
  • 線程創(chuàng)建:當(dāng)使用此工廠創(chuàng)建線程時(shí),它調(diào)用newThread(Runnable r)方法。
  • 線程命名:newThread(Runnable r)方法創(chuàng)建一個(gè)新的Thread對(duì)象并設(shè)置默認(rèn)線程名稱。
  • 線程組分配:新線程被分配到一個(gè)默認(rèn)線程組。
  • 線程優(yōu)先級(jí)和守護(hù)狀態(tài):線程優(yōu)先級(jí)設(shè)置為默認(rèn)值,如果初始為守護(hù)線程,則將其設(shè)置為非守護(hù)線程。

(4) 示例

雖然無(wú)法看到defaultThreadFactory的精確實(shí)現(xiàn),但我們可以提供一個(gè)示例實(shí)現(xiàn)來(lái)演示如何創(chuàng)建具有默認(rèn)屬性的線程

public class DefaultThreadFactory implements ThreadFactory {
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s!= null)? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" +
                     poolNumber.getAndIncrement() +
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r,
                              namePrefix + threadNumber.getAndIncrement(),
                              0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority()!= Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

在這個(gè)示例中,DefaultThreadFactory使用AtomicInteger確保池和線程編號(hào)的唯一性。創(chuàng)建的線程名稱具有前綴“pool-x-thread-y”,其中 x 和 y 是遞增的數(shù)字。線程是非守護(hù)的,其優(yōu)先級(jí)設(shè)置為T(mén)hread.NORM_PRIORITY。

(5) 特性

  • 標(biāo)準(zhǔn)線程屬性:使用defaultThreadFactory創(chuàng)建的線程具有標(biāo)準(zhǔn)的 Java 線程屬性。
  • 非特殊用途:此線程工廠適用于不需要特殊權(quán)限的應(yīng)用程序。
  • 非守護(hù)線程:這些線程的存在將阻止 JVM 退出,直到所有非守護(hù)線程完成執(zhí)行。

(6) 使用場(chǎng)景

  • 標(biāo)準(zhǔn)應(yīng)用程序:適用于大多數(shù)需要具有默認(rèn)屬性線程的標(biāo)準(zhǔn)應(yīng)用程序。
  • ExecutorService 實(shí)現(xiàn):在不需要特殊線程屬性時(shí),通常用作ExecutorService實(shí)現(xiàn)的默認(rèn)選擇。

9. unconfigurableExecutorService(ExecutorService executor)

unconfigurableExecutorService方法在 Java java.util.concurrent包的Executors類(lèi)中,用于創(chuàng)建一個(gè)圍繞ExecutorService的不可配置包裝器。這意味著一旦包裝的ExecutorService被創(chuàng)建,其配置就不能被更改,例如修改池大小或任務(wù)隊(duì)列。

(1) 實(shí)現(xiàn)原理

  • 封裝:將現(xiàn)有的ExecutorService包裝在一個(gè)不可配置的代理中。
  • 不可變配置:任何更改配置的方法調(diào)用,如shutdown、shutdownNow、setCorePoolSize等,都將拋出UnsupportedOperationException。
  • 委托:其他方法調(diào)用被委托給原始的ExecutorService。

(2) 源代碼分析

unconfigurableExecutorService方法的詳細(xì)實(shí)現(xiàn)未完全暴露,因?yàn)樗荅xecutors類(lèi)的私有方法的一部分。然而,我們可以根據(jù)ExecutorService接口和代理機(jī)制推斷其行為。

以下是unconfigurableExecutorService方法的典型調(diào)用:

public static ExecutorService unconfigurableExecutorService(ExecutorService executor) {
    return new FinalizableDelegatedExecutorService(executor);
}

FinalizableDelegatedExecutorService是Executors類(lèi)中的私有靜態(tài)內(nèi)部類(lèi),實(shí)現(xiàn)了ExecutorService接口,并將方法調(diào)用委托給另一個(gè)ExecutorService。

(3) 實(shí)現(xiàn)過(guò)程

  • 初始化:調(diào)用unconfigurableExecutorService方法時(shí),返回一個(gè)新的FinalizableDelegatedExecutorService實(shí)例,該實(shí)例將原始的ExecutorService作為參數(shù)。
  • 方法攔截:對(duì)FinalizableDelegatedExecutorService方法的調(diào)用首先被攔截。
  • 配置修改攔截:如果方法是用于修改配置的,如shutdown或shutdownNow,則拋出UnsupportedOperationException。
  • 委托其他調(diào)用:不涉及配置修改的調(diào)用,如submit或execute,被委托給原始的ExecutorService。

(4) 示例

以下是一個(gè)示例實(shí)現(xiàn),演示如何創(chuàng)建一個(gè)不可配置的ExecutorService代理:

public class UnconfigurableExecutorService implements ExecutorService {
    private final ExecutorService executor;

    public UnconfigurableExecutorService(ExecutorService executor) {
        this.executor = executor;
    }

    @Override
    public void shutdown() {
        throw new UnsupportedOperationException("Shutdown not allowed");
    }

    @Override
    public List<Runnable> shutdownNow() {
        throw new UnsupportedOperationException("Shutdown not allowed");
    }

    @Override
    public boolean isShutdown() {
        return executor.isShutdown();
    }

    @Override
    public boolean isTerminated() {
        return executor.isTerminated();
    }

    @Override
    public void execute(Runnable command) {
        executor.execute(command);
    }
}

在這個(gè)示例中,UnconfigurableExecutorService攔截shutdown和shutdownNow方法并拋出UnsupportedOperationException。其他方法直接委托給原始的ExecutorService。

(5) 特性

  • 不可變配置:創(chuàng)建的ExecutorService包裝器確保線程池的配置不能被外部更改。
  • 共享環(huán)境中的安全性:有助于防止意外更改線程池的狀態(tài),提高多線程環(huán)境中的安全性。
  • 維護(hù)原始行為:其他方法保留原始ExecutorService的行為。

(6) 使用場(chǎng)景

  • 共享線程池:適用于多個(gè)組件共享同一個(gè)線程池的情況,防止一個(gè)組件意外修改配置。
  • 受控環(huán)境:在需要線程池配置保持一致且不可更改的環(huán)境中很有用。
責(zé)任編輯:趙寧寧 來(lái)源: 程序猿技術(shù)充電站
相關(guān)推薦

2017-11-03 10:40:25

Python復(fù)制文件方法

2019-11-13 14:38:34

Executors阿里線程池

2024-02-28 07:37:53

JavaExecutors工具

2024-12-30 08:20:29

程序并發(fā)任務(wù)線程

2015-09-10 09:30:54

Java多線程同步

2023-03-07 15:47:15

2022-01-16 09:30:34

Ansible自動(dòng)化工具開(kāi)源

2025-04-17 08:47:23

2024-01-03 08:15:35

Executors線程池線程

2024-04-24 10:47:20

物聯(lián)網(wǎng)智能建筑

2022-07-07 00:33:34

Java線程同步

2021-08-18 11:55:25

Python函數(shù)代碼

2023-05-17 10:53:43

AICIO

2009-06-29 18:18:53

Java多線程向線程傳遞數(shù)據(jù)

2023-06-02 10:02:17

AICIO供應(yīng)商

2019-09-05 09:54:01

Java產(chǎn)品經(jīng)理人生第一份工作

2023-08-03 16:02:24

Objectwaitnotify

2024-01-10 08:20:50

Linux編輯器pico

2022-08-29 09:06:43

hippo4j動(dòng)態(tài)線程池

2021-12-27 14:20:45

Linux Linux命令
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)