主线程等待多个子线程执行业务代码(查询、计算或其他耗时操作)完成后继续执行。
//从实际业务中抽象出来的 Demo
CountDownLatch countDownLatch = new CountDownLatch(2);
new Thread(() - >{
*** // 业务
countDownLatch.countDown();
}).start();
new Thread(() - >{
*** // 业务
countDownLatch.countDown();
}).start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
//日志记录
}
在业务中,可能需要大量使用线程来执行业务代码,所有在编写请求线程类时,需要考虑traceId,即:在线程内也可追踪完整的请求链路。
// 从业务中的PostRequestThread类 抽象出的Demo
public class PostDemo implements Runnable {
private String url;
private JSONObject result; // 应答结果
private String traceId = "";
public PostRequestThread(String url,Map<String,String> paramMap) {
this.url = url;
this.traceId = LoggerUtils.getTraceId();
}
@Override
public void run() {
LoggerUtils.setTraceId(traceId);
try {
//
} catch (Exception e) {
// 日志记录
}
}
public JSONObject getResult(){
return result;
}
}
项目中如何从请求到后端时,就开始做日志记录,使用切面类,在所有被@RequestMapping注解修饰的方法都被织入。
@Aspect //申明为切面类
@Component //交由Spring容器管理
public class ControllerAspect {
private static final String pointcutValue = "pointcut()";
private static final String exeValue = "@annotation(org.springframework.web.bind.annotation.RequestMapping)"
@Pointcut(exeValue)
private void pointcut(){}
@Before(pointcutValue)
public void before (JoinPoint joinPoint) {
logIn(joinPoint.getArgs());
startTime.set(CommonLogger.currentTimeMillis());
}
@AfterReturning(pointcut=pointcutValue,returning="rtv")
public void afterReturning(JoinPoint joinPoint,Object rtv) {
try {
JSONObject resultJson;
}
}
}
学习使用stream进行流处理。
// 从 judicialCaseDetailExport 方法中抽象出来的 Demo
List<A> values = getData();
List<B> result = new ArrayList<>();
Optional.ofNullable(values).ifPresent(values -> {
result.addAll(values.paralleStream.map( bean -> {
B b = new B();
b.set**(bean.get**());
//获取有用信息填充到 b 中
return b;
}))
})
return result;