示意图
主线程: 绿色线,请求直接执行业务代码, 业务代码执行立即响应
异步线程一: 记录请求日志
异步线程二:获取记录请求日志返回的数据,在数据中在插入响应日志, (这里如果业务代码执行完毕了但线程一还在执行中, 就等待线程一执行完再执行线程二)
1、定义线程池
/**
* 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
*/
final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
2、开启异步线程执行 log 方法
使用 fixedThreadPool.submit
执行线程, 线程执行完将可以使用 future.get()
获取返回值
// 1、记录请求日志, 将异步执行(与业务代码并行处理),不影响程序响应, future 为线程的返回值,用于后面异步执行响应结果
Future<AdminLog> future = fixedThreadPool.submit(new Callable<AdminLog>() {
@Override
public AdminLog call() {
return log(proceed, sra.getRequest(), sra.getResponse());
}
});
3、执行业务方法
// 执行业务
Object obj = proceed.proceed();
4、异步执行业务后的代码
future.isDone() 可以判断 异步线程执行 log 的方法是否执行完成, 完成后可获取返回值
// 异步记录请求结果
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
while (true) {
// 判断记录请求日志是否记录完成(true=完成)
if (future.isDone()) {
AdminLog log = null;
try {
log = future.get();
} catch (Exception e) {
e.printStackTrace();
}
updLog(log.getId(), state, executeTime, businessTime, obj);
break;
}
}
}
});