使用場景
之前在實現(xiàn)熔斷降級組件時穴吹,需要實現(xiàn)一個接口的超時中斷,意思是缰泡,業(yè)務(wù)在使用熔斷降級功能時刀荒,在平臺上設(shè)置了一個超時時間,如果在請求進入熔斷器開始計時棘钞,并且接口在超時時間內(nèi)沒有響應(yīng)缠借,則需要提早中斷該請求并返回。
比如正常下游接口的超時時間為800ms宜猜,但是因為自身業(yè)務(wù)的特殊需求泼返,最多只能等200ms,如果200ms之內(nèi)沒有數(shù)據(jù)返回姨拥,則返回降級數(shù)據(jù)绅喉。這里處理請求的線程可以看成是tomcat線程池中的一個線程,如果通過線程池返回的Future叫乌,可以很輕松的實現(xiàn)超時返回柴罐。
超過自己的預(yù)設(shè)值,直接返回失敗憨奸,并且記錄一下失敗日志革屠,可以自己決定是否需要重試。
主要方法
因為需要有返回值,但是實現(xiàn) Runable 似芝,重寫 run 方法沒有返回值那婉,
所以我們采用實現(xiàn)Callable的方式,重寫 call 方法就行
如何得到返回值呢党瓮?
task.get()
注意的是详炬,默認不設(shè)置時間,這個是無限等待堵塞在那里的寞奸。
所以還提供了另外的方法
task.get(2500, TimeUnit.MILLISECONDS);
加個參數(shù)表示超時時間呛谜。
public class CallableDemo {
public static String fun() {
// 成員內(nèi)部類
class CallableThread implements Callable<String> {
@Override
public String call() {
try {
// 假設(shè)這個是一個耗時的網(wǎng)絡(luò) 請求
Thread.sleep(6000);
return "請求返回值";
} catch (InterruptedException e) {
// 假裝記錄一下日志
return null;
}
}
}
// 開始事件
long beginTime = System.currentTimeMillis();
Callable<String> callableThread=new CallableThread();
FutureTask<String> task= new FutureTask<>(callableThread);
// 開啟線程
new Thread(task).start();
String result;
try {
// 如果2.5秒沒有返回值就 拋出異常
result = task.get(2500, TimeUnit.MILLISECONDS);
} catch (Exception e) {
result=null;
}
// 結(jié)束事件
long endTime = System.currentTimeMillis();
System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!");
if (result!=null){
return result;
}else {
return null;
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(fun());
}
}