Skip to content

面试速答(先看这里)

**一句话结论:**有的时候,我们需要实现这样的功能,比如说我们有多个黑名单需要校验,为了提升效率,需要并发执行,执行过程中,如果有结果先返回了,就判断他是否命中了黑名单,如果命中,则不用再等后续的其他请求了,直接拒绝即可,否则就要等所有的请求都返回,所有的返回都是通过,返回通过。

60秒标准回答:

有的时候,我们需要实现这样的功能,比如说我们有多个黑名单需要校验,为了提升效率,需要并发执行,执行过程中,如果有结果先返回了,就判断他是否命中了黑名单,如果命中,则不用再等后续的其他请求了,直接拒绝即可,否则就要等所有的请求都返回,所有的返回都是通过,返回通过

想要实现这个功能,可以借助 CompletionService

CompletionService是Java8的新增接口,JDK为其提供了一个实现类ExecutorCompletionService。这个类是为线程池中Task的执行结果服务的,即为Executor中Task返回Future而服务的

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**想要实现这个功能,可以借助 CompletionService 。
  • **要点2:**CompletionService是Java8的新增接口,JDK为其提供了一个实现类ExecutorCompletionService。
  • **要点3:**CompletionService的实现目标是任务先完成可优先获取到,即结果按照完成先后顺序排序。

**记忆锚点:**CompletionService → Task → Executor → 并发调三个方法 → 这个类是为线程 → Future

加分表达:

  • 有的时候,我们需要实现这样的功能,比如说我们有多个黑名单需要校验,为了提升效率,需要并发执行,执行过程中,如果有结果先返回了,就判断他是否命中了黑名单,如果命中,则不用再等后续的其他请求了,直接拒绝即可,否则就要等所有的请求都返回,所有的返回都是通过,返回通过。

追问准备:

  • 围绕「CompletionService」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「Task」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「Executor」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

有的时候,我们需要实现这样的功能,比如说我们有多个黑名单需要校验,为了提升效率,需要并发执行,执行过程中,如果有结果先返回了,就判断他是否命中了黑名单,如果命中,则不用再等后续的其他请求了,直接拒绝即可,否则就要等所有的请求都返回,所有的返回都是通过,返回通过。

想要实现这个功能,可以借助CompletionService。

CompletionService是Java8的新增接口,JDK为其提供了一个实现类ExecutorCompletionService。这个类是为线程池中Task的执行结果服务的,即为Executor中Task返回Future而服务的。

CompletionService的实现目标是任务先完成可优先获取到,即结果按照完成先后顺序排序。

image.png

主要的代码实现如下:

yaml
//先创建一个线程池
ScheduledExecutorService blackListCheckExecutorService = new ScheduledThreadPoolExecutor(20,
            new BasicThreadFactory.Builder().namingPattern("multi-black-list-decision-%d").build());
            
//定义一个CompletionService,返回值为boolean类型 
CompletionService<Boolean> completionService = new ExecutorCompletionService<>(blackListCheckExecutorService);

//把要执行的任务提交给completionService
for (String blackListName : multiBlackListDecisionObject.getBlackListNames()) {
    completionService.submit(() -> getData(new BlackListDecisionObject(multiBlackListDecisionObject, blackListName)) != null);
}

try {
    int tasks = multiBlackListDecisionObject.getBlackListNames().size();
  	//再循环中不断尝试get返回结构
    while (tasks > 0) {
        Future<Boolean> future = completionService.take();
        boolean result = future.get();
      	//拿到一个结果后就判断是否为true
      	//只要有一个为true直接返回true
        if (result) {
            return true;
        }

        tasks--;
    }
  	//都执行完之后,没有true,则最终返回一次false
    return false;
} catch (InterruptedException | ExecutionException e) {
    return false;
}