手寫一個重試機制程序(使用Callable) 原

java.util.concurrent.Callable<V>接口可以實現多線程,同時還能實現一個簡易重試機制。

查看Callable接口源碼可知,它內部的call()方法帶返回值,同時拋出了異常。


public interface Callable<V> {
    V call() throws Exception;
}

那麼咱們可以根據返回值的存在情況,來作爲重試的依據:如果返回值存在,證明重試操作完成;如果返回值不存在,繼續進行重試。

	/**
	 * 
	*
	* @Title: retry 
	* @Description:  重試方法 
	* @param @param count 重試次數
	* @param @param callAble 重試回調
	* @param @param interval 時間間隔 單位:ms
	* @param @return    設定文件 
	* @return T    返回類型 
	* @throws
	 */
	public static <T> T retry(int count,Callable<T> callAble,Long interval){
		
		T t=null;
		for (int i = 0; i < count; i++) {
			try {
				System.out.println("retry on: "+i);
				t=callAble.call();
              System.out.println("Callable call :"+t.toString());
			} catch (Exception e) {
				//發生異常證明一次重試失敗
				System.err.println("retry error: "+e.getMessage());
			}
			if(t!=null) break;
			//重試時間間隔,不爲空/不爲0
			if(interval!=null && interval.longValue()!=0){
				try {
					Thread.sleep(interval.longValue());
				} catch (InterruptedException e) {
					System.err.println("InterruptedException: "+e.getMessage());
				}
			}
		}
		return t;
		
	}

我在重試方法中添加的重試次數和間隔時間的控制,基本可以滿足重試機制的要求了。

測試下:

1、代碼拋出異常,無法返回數據,一直進行重試操作

public class Main {

	
	public static void main(String[] args) throws Exception {
		Callable<String> callAble=new Callable<String>(){

			@Override
			public String call() throws Exception {
				System.out.println("----------call");
				System.out.println("當前線程名——" + Thread.currentThread().getName());
				throw new RuntimeException();
//				return "3";
			}
			
		};
		RetryUtil.retry(3, callAble,2000l);
	}
	
	
}

運行結果:

retry on: 0
----------call
當前線程名——main
retry error: null

retry on: 1
----------call
當前線程名——main
retry error: null

retry on: 2
----------call
retry error: null
當前線程名——main

2、代碼正常運行,並能正常返回數據,重試一次便結束

	public static void main(String[] args) throws Exception {
		Callable<String> callAble=new Callable<String>(){

			@Override
			public String call() throws Exception {
				System.out.println("----------call");
				System.out.println("當前線程名——" + Thread.currentThread().getName());
//				throw new RuntimeException();
				return "3";
			}
			
		};
		RetryUtil.retry(3, callAble,2000l);
	}

運行結果:

retry on: 0
----------call
當前線程名——main
Callable call :3





通過測試可以看出,代碼基本滿足了重試機制的要求。

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