1. 程式人生 > >實現出現異常可重複執行的執行緒池-功能實現(1)

實現出現異常可重複執行的執行緒池-功能實現(1)

因為多執行緒是程式單獨的在另一個執行緒裡執行,這樣出現了異常我們的主執行緒是監測不到的。有時候我們希望當程式發生異常時,還能再去進行重試,當達到重試次數後在進行異常的處理。

首先我們定義一個回撥介面,類似於Runnable介面,如下:

public interface  QltRunnable{
    /**
     * 程式正常的執行邏輯
     */
   void run() ;

    /**
     * 當達到最大重試次數後異常的處理邏輯
     */
   void error(Exception e) ;
}

 然後我們定義我們自己的執行緒池物件,如下:

public class QltThreadPoolExecutor{
    
    private ThreadPoolExecutor threadPoolExecutor;
    //重試次數
    private int retry=3;
    //執行緒池大小
    private int size=1;

    public QltThreadPoolExecutor(){
        //無參構造方法 預設執行緒數大小為電腦的核心數
        this(Runtime.getRuntime().availableProcessors());
    }

    public QltThreadPoolExecutor(int threadCount){
        this.size=threadCount;
        threadPoolExecutor= (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount);
    }

    /**
     * 對外暴露的可執行的方法
     * @param runnable
     */
    public void execute(final QltRunnable runnable){
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                execute(runnable,0);
            }
        });
    }

    private void execute(final QltRunnable runnable, int retryCount){
        try {
            runnable.run();
        }catch (Exception e){
            //如果小於重試次數,則進行重試
            if(retryCount<retry){
                execute(runnable,++retryCount);
            }else{
                //超過設定的重試次數 則進行異常處理
                runnable.error(e);
            }
        }
    }
    
    public ThreadPoolExecutor getThreadPoolExecutor() {
        return threadPoolExecutor;
    }

    public int getRetry() {
        return retry;
    }

    public void setRetry(int retry) {
        this.retry = retry;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
        threadPoolExecutor.setCorePoolSize(size);
        threadPoolExecutor.setMaximumPoolSize(size);
    }

}

現在我們的功能就實現了,實現的非常的簡單,用起來也很簡單。

1、可以手動的去new一個使用,如下:

 //執行緒數設定為5
QltThreadPoolExecutor executor=new QltThreadPoolExecutor(5);
//開啟一個執行緒
 executor.execute(new QltRunnable() {
            @Override
            public void run() {
                int i=6/0;
            }

            @Override
            public void error(Exception e) {
                System.out.println("出錯了");
            }
        });

2、使用spring配置:

<bean class="cn.qlt.common.utils.concurrent.QltThreadPoolExecutor">
    <!--執行緒池大小-->
    <property name="size" value="10"/>
    <!--重試次數-->
    <property name="retry" value="5"/>
</bean>

 然後在程式中我們將其注入即可。

總結:該功能的實現非常簡單,即我們自定義了回撥的物件。並結合java的執行緒池實現了該功能。但感覺spring的配置還略微麻煩,下面一節我們來自定義spring標籤