色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術文章
文章詳情頁

Java中有界隊列的飽和策略(reject policy)原理解析

瀏覽:73日期:2022-09-02 13:19:18

我們在使用ExecutorService的時候知道,在ExecutorService中有個一個Queue來保存提交的任務,通過不同的構造函數,我們可以創建無界的隊列(ExecutorService.newCachedThreadPool)和有界的隊列(ExecutorService newFixedThreadPool(int nThreads))。

無界隊列很好理解,我們可以無限制的向ExecutorService提交任務。那么對于有界隊列來說,如果隊列滿了該怎么處理呢?

今天我們要介紹一下java中ExecutorService的飽和策略(reject policy)。

以ExecutorService的具體實現ThreadPoolExecutor來說,它定義了4種飽和策略。分別是AbortPolicy,DiscardPolicy,DiscardOldestPolicy和CallerRunsPolicy。

如果要在ThreadPoolExecutor中設定飽和策略可以調用setRejectedExecutionHandler方法,如下所示:

ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(20)); threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy() );

上面的例子中我們定義了一個初始5個,最大10個工作線程的Thread Pool,并且定義其中的Queue的容量是20。如果提交的任務超出了容量,則會使用AbortPolicy策略。

AbortPolicy

AbortPolicy意思是如果隊列滿了,最新的提交任務將會被拒絕,并拋出RejectedExecutionException異常:

public static class AbortPolicy implements RejectedExecutionHandler { /** * Creates an {@code AbortPolicy}. */ public AbortPolicy() { } /** * Always throws RejectedExecutionException. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task * @throws RejectedExecutionException always */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException('Task ' + r.toString() + ' rejected from ' + e.toString()); } }

上面的代碼中,rejectedExecution方法中我們直接拋出了RejectedExecutionException異常。

DiscardPolicy

DiscardPolicy將會悄悄的丟棄提交的任務,而不報任何異常。

public static class DiscardPolicy implements RejectedExecutionHandler { /** * Creates a {@code DiscardPolicy}. */ public DiscardPolicy() { } /** * Does nothing, which has the effect of discarding task r. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } }

DiscardOldestPolicy

DiscardOldestPolicy將會丟棄最老的任務,保存最新插入的任務。

public static class DiscardOldestPolicy implements RejectedExecutionHandler { /** * Creates a {@code DiscardOldestPolicy} for the given executor. */ public DiscardOldestPolicy() { } /** * Obtains and ignores the next task that the executor * would otherwise execute, if one is immediately available, * and then retries execution of task r, unless the executor * is shut down, in which case task r is instead discarded. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) {e.getQueue().poll();e.execute(r); } } }

我們看到在rejectedExecution方法中,poll了最老的一個任務,然后使用ThreadPoolExecutor提交了一個最新的任務。

CallerRunsPolicy

CallerRunsPolicy和其他的幾個策略不同,它既不會拋棄任務,也不會拋出異常,而是將任務回退給調用者,使用調用者的線程來執行任務,從而降低調用者的調用速度。我們看下是怎么實現的:

public static class CallerRunsPolicy implements RejectedExecutionHandler { /** * Creates a {@code CallerRunsPolicy}. */ public CallerRunsPolicy() { } /** * Executes task r in the caller’s thread, unless the executor * has been shut down, in which case the task is discarded. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) {r.run(); } } }

在rejectedExecution方法中,直接調用了 r.run()方法,這會導致該方法直接在調用者的主線程中執行,而不是在線程池中執行。從而導致主線程在該任務執行結束之前不能提交任何任務。從而有效的阻止了任務的提交。

使用Semaphore

如果我們并沒有定義飽和策略,那么有沒有什么方法來控制任務的提交速度呢?考慮下之前我們講到的Semaphore,我們可以指定一定的資源信號量來控制任務的提交,如下所示:

public class SemaphoreUsage { private final Executor executor; private final Semaphore semaphore; public SemaphoreUsage(Executor executor, int count) { this.executor = executor; this.semaphore = new Semaphore(count); } public void submitTask(final Runnable command) throws InterruptedException { semaphore.acquire(); try { executor.execute(() -> { try { command.run(); } finally { semaphore.release(); } } ); } catch (RejectedExecutionException e) { semaphore.release(); } }}

本文的例子可參考https://github.com/ddean2009/learn-java-concurrency/tree/master/rejectPolicy

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 久久在线观看免费视频 | 日韩一区二区三区视频在线观看 | 国产一区二区中文字幕 | 99视频精品全部在线播放 | 免费一级成人免费观看 | 在线免费观看一区二区三区 | 日韩中文字幕视频 | 免费伦费一区二区三区四区 | 国产日韩免费 | 久久久久久久岛国免费观看 | 日韩一级免费视频 | 一级女性全黄生活片免费 | 国产亚洲一欧美一区二区三区 | 欧美亚洲一区二区三区在线 | 色悠久久久久综合网伊人男男 | 欧美国产日本 | 中文一区在线 | 亚洲精品国产高清不卡在线 | 欧美一区二区在线 | 国产精品亚洲一区二区三区在线观看 | 成人午夜 | 九九九九热精品视频 | 欧美成人免费xxx大片 | 欧美巨大video粗暴 | 在线成人免费看大片 | 日本三片在在线播放 | 国产日产亚洲精品 | 成人免费视频网站 | 一区二区三区免费精品视频 | 国产日韩线路一线路二 | 视频一区二区三区在线 | 国产高清视频免费最新在线 | 国产精选一区二区 | 亚洲精品理论 | 全黄a一级毛片 | 久久经典免费视频 | 国产亚洲欧美成人久久片 | 美国一级片在线观看 | 欧美黑人性xxx猛交 欧美很黄视频在线观看 | 国产一区二区在线视频 | 波多野吉衣 免费一区 |