1. 程式人生 > >Java執行緒池-自定義拒絕策略

Java執行緒池-自定義拒絕策略

Q: 什麼時候需要使用拒絕策略呢?
A: 當任務數量超過系統實際承載能力的時候就要用到拒絕策略了,可以說它是系統超負荷執行的補救措施。簡言之,就是執行緒用完,佇列已滿,無法為新任務服務,則需一套機制來合理的處理這些問題。

JDK 提供了四種內建拒絕策略,我們要理解並記住,有如下的四種:
1、DiscardPolicy: 默默丟棄無法處理的任務,不予任何處理
2、DiscardOldestPolicy: 丟棄佇列中最老的任務, 嘗試再次提交當前任務
3、AbortPolicy: 直接拋異常,阻止系統正常工作。
4、CallerRunsPolicy: 將任務分給呼叫執行緒來執行,運行當前被丟棄的任務,這樣做不會真的丟棄任務,但是提交的執行緒效能有可能急劇下降。

以下是我們通常的使用方式:

int corePoolSize = 1;
int maximumPoolSize = 1;
BlockingQueue queue = new  ArrayBlockingQueue<Runnable>(1);
ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize,  maximumPoolSize,0, TimeUnit.SECONDS, queue ) ;
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy ());
pool.setRejectedExecutionHandler(new
ThreadPoolExecutor.AbortPolicy()); pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

但有時候我們需要對改介面進行擴充套件,來滿足特別的需求就需要自定義了。

拒絕策略的介面實現
public interface RejectedExecutionHandler {
    void rejectedExecution(Runnable r, 
    ThreadPoolExecutor executor);
}
自定義拒絕策略的程式碼示例
public class RejectThreadPoolDemo {
    public static class MyTask implements Runnable {
        @Override
        public void run() {
            System.out.println(System.currentTimeMillis()
                    + ":Thread ID:" + Thread.currentThread().getId());
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) throws InterruptedException {
        MyTask myTask = new MyTask();

        ExecutorService executorService = new ThreadPoolExecutor(5, 5, 0L,
            TimeUnit.SECONDS, 
            new LinkedBlockingDeque<Runnable>(10),   
            Executors.defaultThreadFactory()
                , new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                //列印丟棄的任務
                System.out.println(r.toString() + " is discard");
            }
        });
        for (int i = 0; i < 100; i++) {
            executorService.submit(myTask);
            Thread.sleep(10);
        }
    }
}

上面自定義了一個執行緒池有5個常駐執行緒,最大執行緒數量也是5個,等待佇列設為10,同時在這裡自定義了拒絕策略,列印被丟棄的任務資訊。

輸出如下:
[email protected] is discard
[email protected] is discard
[email protected] is discard
[email protected] is discard
1528709221737:Thread ID:10
1528709221752:Thread ID:11

思考:
  1. Java中有哪些無界佇列和有界佇列?
  2. 為什麼生產上不能使用無界佇列?

下一次分享讓我們探討一下有界、無界佇列對ThreadPoolExcutor執行的影響,歡迎小夥伴們留言討論~~

相關推薦

Java執行-定義拒絕策略

Q: 什麼時候需要使用拒絕策略呢? A: 當任務數量超過系統實際承載能力的時候就要用到拒絕策略了,可以說它是系統超負荷執行的補救措施。簡言之,就是執行緒用完,佇列已滿,無法為新任務服務,則需一套機制來合理的處理這些問題。 JDK 提供了四種內建拒

java執行引數說明及佇列拒絕策略

 java.util.concurrent.ThreadPoolExecutor,其構造方法1: public ThreadPoolExecutor(int corePoolSize, int maximumP

Java執行拒絕策略

一、簡介   jdk1.5 版本新增了JUC併發程式設計包,極大的簡化了傳統的多執行緒開發。前面文章中介紹了執行緒池的使用,連結地址:https://www.cnblogs.com/eric-fang/p/9004020.html   Java執行緒池,是典型的池化思想的產物,類似的還有資料庫的連線池、red

總結下java執行的處理策略

執行緒池 任務提交給執行緒池之後的處理策略: 如果當前執行緒池中的執行緒數目<corePoolSize,則每來一個任務,就會建立一個執行緒去執行這個任務; 如果當前執行緒池中的執行緒數目>=corePoolSize,則每來一個任務,會嘗試將其新增到任務快取隊列當中,若

從零開始學多執行定義配置執行(七)

等待其他資源,可能會產生執行緒飢餓死鎖 線上程池中如果一個任務依賴於其它任務的執行,就可能產生死鎖.在一個單執行緒化的Executor中,提交兩個任務,任務二滯留在工作佇列中等待第一個任務完成,但是第一個任務不會完成,因為它在等待第二個任務的完成(需要第二個任務執行的結果進行運算),這就會發生死鎖. 在一個大

限制Java執行執行執行以及等待執行數量的策略

對於 java.util.concurrent.Executors 所提供的 FixedThreadPool ,可以保證可以在記憶體中有固定數量的執行緒數執行。但是由於 FixedThreadPool 繫結的是 LinkedBlockingQueue 。佇列的上限沒有限制(預設上限為 Int

java執行的核心執行數與最大的執行數的區別,飽和策略

1、當提交一個新任務到執行緒池時首先執行緒池判斷基本執行緒池(corePoolSize)是否已滿?沒滿,建立一個工作執行緒來執行任務。滿了,則進入下個流程;其次執行緒池判斷工作佇列(workQueue)是否已滿?沒滿,則將新提交的任務儲存在工作佇列裡。滿了,則進入下個流程;最

Java執行技術之二 Java執行實現

一,介紹   類檢視如下:     自Java 1.5後,Java對執行緒相關的庫做了很大的拓展,執行緒池就是其中之一。Java執行緒的新特性多數在java.util.concurrent,其包含眾多的介面和類。其中java.util.concurrent.Execut

java執行詳細入門教程即原始碼解析

##1、執行緒池概念      執行緒池是執行緒的集合,通過執行緒池我們不需要自己建立執行緒,將任務提交給執行緒池即可。為什麼要使用執行緒池,首先,使用執行緒池可以重複利用已有的執行緒繼續執行任務,避免執行緒在建立和銷燬時造成的消耗。其次,由

Java執行ThreadPoolExecutor詳解

  1、執行緒池的工作原理?   執行緒池剛建立時,裡面沒有一個執行緒。任務佇列是作為引數傳進來的。不過,就算佇列裡面有任務,執行緒池也不會馬上執行它們。 當呼叫 execute() 方法新增一個任務時,執行緒池會做如下判斷:

java 執行 ExecutorService相關歸納

public class ExecutorServiceDemo {     public static void main(String[] args) {          // 單執行緒池  &

Java執行Executor框架詳解

Java的執行緒既是工作單元,也是執行機制。從JDK 5開始,把工作單元與執行機制分離開來。工作單元包括Runnable和Callable,而執行機制由Executor框架提供。 Executor框架簡介在HotSpot VM的執行緒模型中,Java執行緒(java.lang.Thread)被一對一對映為本

java執行(有返回值和無返回值)

無返回值: package ThreadPool2; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class test { public stat

揭祕Java執行的真相

執行緒池是指在初始化一個多執行緒應用程式過程中建立一個執行緒集合,然後在需要執行新的任務時重用這些執行緒而不是新建一個執行緒。執行緒池中執行緒的數量通常完全取決於可用記憶體數量和應用程式的需求。然而,增加可用執行緒數量是可能的。執行緒池中的每個執行緒都有被分配一個任務,一旦任務已經完成了,執行緒

Java執行的認識、常用執行的分析

什麼是程式,什麼是程序,什麼是執行緒,他們有什麼區別?   程式是指令和資料的有序集合,其本身並沒有任何執行的含義,是一個靜態的概念。 程序是一個動態的過程,是一個活動的實體。簡單來說,一個應用程式得到執行就可以看作是一個程序。程序可以包含多個同時執行的執行緒。程序也是擁有系統

【小家Java】一次Java執行誤用(newFixedThreadPool)引發的線上血案和總結

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

【小家javaJava執行之---ForkJoinPool執行的使用以及原理

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

java執行淺析

簡介        執行緒的使用在 java 中佔有極其重要的地位,在 jdk1.4 極其之前的 jdk 版本中,關於執行緒池的使用是極其簡陋的。在 jdk1.5 之後這一情況有了很大的改觀。Jdk1.5 之後加入了java.util.concu

Java執行的疑問

閱讀《Java程式設計思想》第四版,根據書上的程式碼建立執行緒池。 ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < count; i++) {

Java執行的實現--Executor、ThreadPoolTaskExecutor、@Async的使用

一、為什麼要使用執行緒池 當我們需要的併發執行執行緒數量很多時,且每個執行緒執行很短的時間就結束了,這樣,我們頻繁的建立、銷燬執行緒就大大降低了工作效率(建立和銷燬執行緒需要時間、資源)。java中的執行緒池可以達到這樣的效果:一個執行緒執行完任務之後,繼續去執行下一個任務,