總結兩種線程池的任務拒絕策略

        在多任務執行的時候,我們可能用到線程池,如果在任務量非常大的情況下任務可能走了拒絕策略,有人可能會說那就吧隊列設置成最大的,或者無界隊列的情況,這種方式是可以暫時解決任務丟失的情況,但是如果隊列如果太多一直阻塞可能會造成OOM。所以再網上看了一些文檔,在拒絕策略那總結了兩種方式,並在生產驗證了這兩種情況:

(1)直接在拒絕那重新給隊列添加任務,重複添加,直到隊列中有空位騰出

(2)在拒絕策略那塊,可以再次補償執行添加任務,直到成功爲止

代碼如下:

方式一:

package com.eebbk.content.ai.makequestion.config;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Auther: lipf
 * @Date: 2020/1/13 16:50
 * @Description:
 */
@Slf4j
public class CustomAbortPolicy implements RejectedExecutionHandler {

    public void AbortPolicy() { }

    /**
     * Always throws RejectedExecutionException.
     * @param r the runnable task requested to be executed
     * @throws RejectedExecutionException always
     */
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (!executor.isShutdown()) {
            try {
                log.error("full-->>線程池已滿,執行拒絕策略");
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                log.error("interruptedException="+e.toString());
            }
        }
    }
}

方式二:


public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
      if (!executor.isShutdown()) {
          try {
              log.error("full-->>線程池已滿,執行拒絕策略");
              while (e.getQueue().remainingCapacity() == 0);
              e.execute(r);
          } catch (InterruptedException e) {
              log.error("interruptedException="+e.toString());
          }
      }
}

任務測試用例:

    public void testThread(){
        //模擬10000個任務執行,用計時器保證任務最終執行後合併歸一
        CountDownLatch countDownLatch=new CountDownLatch(10000);
        //統計任務是否丟失
        AtomicInteger atomicInteger=new AtomicInteger();
        //模擬10000個任務執行
        for (int i = 0; i < 10000; i++) {
            taskExecutor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        atomicInteger.addAndGet(1);
                    } catch (Exception e) {

                    } finally {
                        countDownLatch.countDown();
                    }
                }
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(atomicInteger);
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章