现在有这样一个场景,用户下单服务(OrderServe)再下但之前需要调用用户服务验证用户信息,要调用账户服务验证账户,要调用贷款服务验证贷款信息,等等,这几个服务异步调用太慢,导致改下单服务非常慢,这几个验证之间有没有任何关联,最终结果所有验证结果都通过就算成功,有一个不通过就失败,则其他验证则立即结束返回失败,所以这几个验证可以同步进行 怎么来优化。
这里我结合FutureTask与CountDownLatch使用
3个服务类,这里只贴一个类 其他一样
/**
* 模拟征信验证
*/
public class RemoteBankService {
public boolean checkAuth(){
boolean flag;
System.out.println("征信验证 - 验证开始");
try {
Thread.sleep(30000);
flag = true;
} catch (InterruptedException e) {
System.out.println("征信验证 - 验证终止");
return false;
}
if(flag){
System.out.println("征信验证 - 验证成功");
return true;
}
else {
System.out.println("征信验证 - 验证失败");
return false;
}
}
}
3个线程 每个线程验证一个事情,这里只贴一个类,其他一样
/**
* 征信验证
*/
public class RemoteBankCallable implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
return new RemoteBankService().checkAuth();
}
}
定义一个CheckFutureTask类集成FutureTask 重写done()方法
public class CheckFutureTask extends FutureTask<Boolean> {
private volatile CountDownLatch latch;
private final int number;
public CheckFutureTask(Callable checkCallable, CountDownLatch latch, int number) {
super(checkCallable);
this.latch = latch;
this.number = number;
}
@Override
protected void done() {
try {
if(!get()){
afterFail();
}
} catch (Exception e) {
afterFail();
} finally {
latch.countDown();
}
}
/**
* 在失败后调用
*/
private void afterFail(){
for(int i = 0 ; i < number - 1 ; i++){
latch.countDown();
}
}
}
定义一个线程工厂
public class MyThreadFactory implements ThreadFactory {
private AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
return new Thread(r,"myThread - " + atomicInteger.incrementAndGet());
}
}
写个main方法 验证以下
public class MainTest {
private static CountDownLatch latch;
/**
* 开始下单
* @param args
*/
public static void main(String[] args) {
final int poolSize = 3;
final int maxPoolSize = poolSize*3;
ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize,maxPoolSize,1, TimeUnit.MINUTES,new LinkedBlockingDeque<>(),new MyThreadFactory());
latch = new CountDownLatch(3);
CheckFutureTask f1 = new CheckFutureTask(new RemoteLoanCallable(),latch,3);
CheckFutureTask f2 = new CheckFutureTask(new RemotePassportCallable(),latch,3);
CheckFutureTask f3 = new CheckFutureTask(new RemoteBankCallable(),latch,3);
executor.execute(f1);
executor.execute(f2);
executor.execute(f3);
try {
latch.await();
//latch 为0后 跳过等待,说明已经之心完毕,如果有一个返回false,则其他正在执行的线程需要终止,所以需要有一个取消操作
f1.cancel(true);
f2.cancel(true);
f3.cancel(true);
//判断结果
if(!f1.get()){
System.out.println(false);
executor.shutdown();
return;
}
if(!f2.get()){
System.out.println(false);
executor.shutdown();
return;
}
if(!f3.get()){
System.out.println(false);
executor.shutdown();
return;
}
} catch (Exception e) {
System.out.println(false);
executor.shutdown();
return;
}
System.out.println(true);
executor.shutdown();
}