问题
项目中需要调用第三方接口,若第三方接口在X秒内未返回,则继续后续业务操作
代码展示
public class CheckTimeOutDemo {
private static ExecutorService threadService = new ThreadPoolExecutor(0,20,60L,TimeUnit.SECONDS,
new SynchronousQueue<>(), r ->{
Thread thread = new Thread(r);
return thread;
});
public static void main(String[] args) {
String s = method(3, 6);
System.out.println(s);
}
/**
* @param threadNum 线程池的数量
* @param timeOut 超时时限
* @return 返回执行结果
*/
public static String method(int threadNum, int timeOut) {
System.out.println(new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date()));
//请求第三方接口
Future<String> future = threadService.submit(
() -> send());
try {
// futrue.get()测试被执行的程序是否能在timeOut时限内返回字符串
return future.get(timeOut, TimeUnit.SECONDS);//任务处理超时时间设为 3 秒
} catch (Exception ex) {
System.out.println(new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date()));
System.out.println("输出异常:" + ex);
} finally {
future.cancel(true);
}
return null;
}
//模拟接口可在本地启动服务,模拟请求三方接口
private static String send() throws IOException {
StuRequest stuRequest = StuRequest.builder().id(111).build();
String obstr = new Gson().toJson(stuRequest);
RequestBody body = RequestBody.create(MediaType.parse("application/json"), obstr);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(200, TimeUnit.SECONDS)
.readTimeout(200, TimeUnit.SECONDS)
.writeTimeout(200, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("http://localhost:8080/login/getstudent").post(body).build();
Response response = okHttpClient.newCall(request).execute();
System.out.println(response.toString());
return response.body().string();
}
}
注意事项
- future.cancel(true) 并不能中断请求,请求结果仍会返回结果。
参数true:如果任务已经被执行,则会尝试中断处理。(中断处理会改变中断标志位,任务应该判断 isInterrupted()或者在任务过程中使用sleep,这样任务才可以被中断)
参数false:如果任务已经被执行,则会等待任务执行完毕。如果是个无线循环任务,将会无法停止。
- 若接口超时,需对超时进行处理,可catch TimeoutException 异常,进行超时业务逻辑处理。